Sorry, my fault - I reposted the wrong link! Try this one:
In fact, I'll save you the visit ...
If you want to cache and replay messages without another node, here is a very simple example flow.
Function
This is the function that is key. As always, it is up to you to keep track of how much memory is being consumed. The replayed messages will go to the client that requested them if it can identify it.
The function only keeps the last 1 message of each topic and this version has no method to clear the cache.
// Expects input msgs with topic set
// saved context
var homeMsgs = context.get('homeMsgs') || {}
// Replay cache if requested
if ( msg.hasOwnProperty('cacheControl') && msg.cacheControl === 'REPLAY' ) {
for (var topic in homeMsgs) {
// Only send to a single client if we can
if ( msg.hasOwnProperty('_socketId') )
node.send({
"topic": topic,
"payload": homeMsgs[topic],
"_socketId": msg._socketId
})
else
node.send({
"topic": topic,
"payload": homeMsgs[topic]
})
}
return null
}
// ignore cacheControl and uibuilder control messages
if ( msg.hasOwnProperty('cacheControl') || msg.hasOwnProperty('uibuilderCtrl') ) return null
// Keep the last msg.payload by topic
homeMsgs[msg.topic] = msg.payload
// save context for next time
context.set('homeMsgs', homeMsgs)
return msg;
Example Flow
Note that the flow doesn't contain the MQTT-in node that drives it. Adapt to your own requirements.
[{"id":"401897b8.9931e8","type":"uibuilder","z":"9974253c.de8db8","name":"","topic":"","url":"home","fwdInMessages":false,"allowScripts":true,"allowStyles":true,"debugFE":false,"copyIndex":true,"x":490,"y":700,"wires":[["d0dec491.704248"],["bbc35ca3.97343","ff280acc.207098"]]},{"id":"d0dec491.704248","type":"debug","z":"9974253c.de8db8","name":"home data out","active":true,"console":"false","complete":"true","x":680,"y":680,"wires":[]},{"id":"889a6459.17d2f8","type":"function","z":"9974253c.de8db8","name":"","func":"// Expects input msgs with topic set\n\n// saved context\nvar homeMsgs = context.get('homeMsgs') || {}\n\n// Replay cache if requested\nif ( msg.hasOwnProperty('cacheControl') && msg.cacheControl === 'REPLAY' ) {\n for (var topic in homeMsgs) {\n // Only send to a single client if we can\n if ( msg.hasOwnProperty('_socketId') )\n node.send({\n \"topic\": topic, \n \"payload\": homeMsgs[topic],\n \"_socketId\": msg._socketId\n })\n else\n node.send({\n \"topic\": topic, \n \"payload\": homeMsgs[topic]\n })\n }\n return null\n}\n\n// ignore cacheControl and uibuilder control messages\nif ( msg.hasOwnProperty('cacheControl') || msg.hasOwnProperty('uibuilderCtrl') ) return null\n\n// Keep the last msg.payload by topic\nhomeMsgs[msg.topic] = msg.payload\n\n// save context for next time\ncontext.set('homeMsgs', homeMsgs)\n\nreturn msg;","outputs":1,"noerr":0,"x":310,"y":700,"wires":[["401897b8.9931e8","b4850396.c9aef"]]},{"id":"bbc35ca3.97343","type":"debug","z":"9974253c.de8db8","name":"home controls","active":true,"console":"false","complete":"true","x":680,"y":720,"wires":[]},{"id":"e35dc750.bbfbe8","type":"link in","z":"9974253c.de8db8","name":"home-replay","links":["ff280acc.207098"],"x":115,"y":700,"wires":[["889a6459.17d2f8"]]},{"id":"ff280acc.207098","type":"link out","z":"9974253c.de8db8","name":"home-controls","links":["e35dc750.bbfbe8"],"x":615,"y":760,"wires":[]},{"id":"b4850396.c9aef","type":"debug","z":"9974253c.de8db8","name":"input messages","active":true,"console":"false","complete":"true","x":480,"y":640,"wires":[]}]
And in case you don't want to install uibuilder. Just note that, to resend the cached info, send in a msg to the function that looks like:
{
"cacheControl": "replay",
"topic": "My Topic"
}
You can use the msg.topic
to control which msg gets replayed. The function will store the last msg of every topic. Obviously, you should take care with memory sizes if you have a lot of topics with lots of data.