Skip to content

How to send data when a client connects or reloads the page

Julian Knight edited this page Jun 26, 2022 · 2 revisions

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.

The Issue

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.

How do we send data when a client browser connects or reloads?

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.

Example Flow

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.

trigger flow

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": []
    }
]
Clone this wiki locally