-
-
Notifications
You must be signed in to change notification settings - Fork 86
How to send data when a client connects or reloads the page
UPDATE June 2022: Since uibuilder v5 was released, there is a new node called uib-cache
. This can be used instead of the workaround shown here. This page may still be useful for reference however. Also note that uibuilder v5.1 will contain the source page reference when a client connects along with a stable client ID. These can be used to help ensure that only the correct cache data is sent to the correct client.
Because of the partial disconnect with web apps between the front- and back-ends, it can be difficult to ensure that a new client browser - or one that simply forces a reload of the page - immediately receives data over the websocket channel.
Of course, one way round this is to keep sending refreshes every few seconds but this is very wasteful.
Instead, we want the back-end, the server, e.g. Node-RED itself, to receive a notification when a client browser connects or reloads so that we can trigger a flow to send the required data. Thankfully, I thought about this as uibuilder
was being created.
Quite simply, we connect the control output from our uibuilder node back to the beginning of the flow.
Then we check for the client connect
and ready for content
control messages, if they are received, we trigger the data collection and send a message back to uibuilder.
We have to remove the msg.uibuilderCtrl
property before sending otherwise the uibuilder front-end code treats the message as a control message and the data change event won't fire. In the example give, this is done in the same change
node that we use to populate the data.
The control msg we are reusing contains the client ID so that the outgoing message only goes to the correct client, it isn't broadcast.
While you probably don't have the global variable that this flow uses, it is easily created. The actual data doesn't really matter, just that something is sent to the client that is connecting/reloading.
Of course, you will want to add other inputs to send updates to all connected clients when the source data is updated, I've not included that in this simple example.
[
{
"id": "5817b2f6.8024bc",
"type": "change",
"z": "fa3e1078.ef619",
"name": "",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "#:(file)::RoomHeatChg",
"tot": "global"
},
{
"t": "delete",
"p": "uibuilderCtrl",
"pt": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 400,
"y": 180,
"wires": [
[
"2697a159.08a8be"
]
]
},
{
"id": "e51bc868.e65df8",
"type": "debug",
"z": "fa3e1078.ef619",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"x": 770,
"y": 140,
"wires": []
},
{
"id": "2697a159.08a8be",
"type": "uibuilder",
"z": "fa3e1078.ef619",
"name": "",
"topic": "",
"url": "dash",
"fwdInMessages": false,
"allowScripts": false,
"allowStyles": false,
"debugFE": false,
"copyIndex": true,
"x": 610,
"y": 180,
"wires": [
[
"e51bc868.e65df8"
],
[
"812d4019.86434"
]
]
},
{
"id": "812d4019.86434",
"type": "link out",
"z": "fa3e1078.ef619",
"name": "Dash Ctrl Out",
"links": [
"dafa5db2.6fc1a"
],
"x": 715,
"y": 220,
"wires": []
},
{
"id": "dafa5db2.6fc1a",
"type": "link in",
"z": "fa3e1078.ef619",
"name": "Dash Ctrl In",
"links": [
"812d4019.86434"
],
"x": 135,
"y": 180,
"wires": [
[
"3283e680.04337a"
]
]
},
{
"id": "3283e680.04337a",
"type": "switch",
"z": "fa3e1078.ef619",
"name": "ui ctrl",
"property": "uibuilderCtrl",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "client connect",
"vt": "str"
},
{
"t": "eq",
"v": "ready for content",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 3,
"x": 230,
"y": 180,
"wires": [
[
"5817b2f6.8024bc"
],
[
"5817b2f6.8024bc"
],
[
"6dded821.4040c8"
]
]
},
{
"id": "6dded821.4040c8",
"type": "debug",
"z": "fa3e1078.ef619",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"x": 370,
"y": 220,
"wires": []
}
]
Please feel free to add comments to the page (clearly mark with your initials & please add a commit msg so we know what has changed). You can contact me in the Discourse forum, or raise an issue here in GitHub! I will make sure all comments & suggestions are represented here.
-
Walkthrough 🔗 Getting started
-
In Progress and To Do 🔗 What's coming up for uibuilder?
-
Awesome uibuilder Examples, tutorials, templates and references.
-
How To
- How to send data when a client connects or reloads the page
- Send messages to a specific client
- Cache & Replay Messages
- Cache without a helper node
- Use webpack to optimise front-end libraries and code
- How to contribute & coding standards
- How to use NGINX as a proxy for Node-RED
- How to manage packages manually
- How to upload a file from the browser to Node-RED
-
Vanilla HTML/JavaScript examples
-
VueJS general hints, tips and examples
- Load Vue (v2 or v3) components without a build step (modern browsers only)
- How to use webpack with VueJS (or other frameworks)
- Awesome VueJS - Tips, info & libraries for working with Vue
- Components that work
-
VueJS v3 hints, tips and examples
-
VueJS v2 hints, tips and examples
- Dynamically load .vue files without a build step (Vue v2)
- Really Simple Example (Quote of the Day)
- Example charts using Chartkick, Chart.js, Google
- Example Gauge using vue-svg-gauge
- Example charts using ApexCharts
- Example chart using Vue-ECharts
- Example: debug messages using uibuilder & Vue
- Example: knob/gauge widget for uibuilder & Vue
- Example: Embedded video player using VideoJS
- Simple Button Acknowledgement Example Thanks to ringmybell
- Using Vue-Router without a build step Thanks to AFelix
- Vue Canvas Knob Component Thanks to Klaus Zerbe
-
Examples for other frameworks (check version before trying)
- Basic jQuery example - Updated for uibuilder v6.1
- ReactJS with no build - updated for uibuilder v5/6
-
Examples for other frameworks (may not work, out-of-date)
-
Outdated Pages (Historic only)
- v1 Examples (these need updating to uibuilder v2/v3/v4/v5)