I am sitting over this for some time now. I want to update the contents of my ui-table if the tab where it is located, is visible.
So far I put this together:
Problems that I have:
1.Everytime I open the Tab with the UI-Table, a new connection to the websocket is established.
2. At the moment it work very inconsistenly, sometimes I get an output directly after entering or leaving the tab, sometimes nothing and sometimes I get several messages at once for one tab browse.
Hope someone here can help me to fix this.
Edit: Since I tend to overthink things, I would be really happy if somebody could offer a different solution to update the contents if the tab is visible.
Content of my function-node:
// Create an array to store connected WebSocket clients
if (!flow.get('clients')) {
flow.set('clients', []);
}
// Function to handle new WebSocket connections
function handleNewConnection(connection) {
// Add the connection to the clients array
flow.get('clients').push(connection);
// Send a welcome message to the new connection
connection.send(JSON.stringify({ message: 'Welcome!' }));
// Handle incoming messages from the client
connection.on('message', function (message) {
// Process the received message
var msg = JSON.parse(message);
// Perform actions based on the tab's active state
// Example: Send the tab's active state to debug output
node.send({ payload: msg.active });
});
// Handle WebSocket connection closure
connection.on('close', function () {
// Remove the connection from the clients array
var clients = flow.get('clients');
var index = clients.indexOf(connection);
if (index !== -1) {
clients.splice(index, 1);
}
});
}
// Check if it's a new WebSocket connection
if (msg.req && msg.req.websocket) {
// Handle new WebSocket connections
handleNewConnection(msg.req.websocket);
}
// Clean up the clients array when the flow is deployed
node.on('close', function () {
flow.set('clients', []);
});
return msg;
Content of my UI-Template:
<script>
// Create a WebSocket connection
var socket = new WebSocket('ws://172.16.19.10:1880/tab-state');
//if(!window.socket){socket = new WebSocket('ws://172.16.19.10:1880/tab-state')};
// Send the tab's active state when it changes
document.addEventListener('visibilitychange', function() {
var isActive = !document.hidden;
socket.send(JSON.stringify({ active: isActive }));
});
// Handle messages from the server
socket.addEventListener('message', function(event) {
var message = JSON.parse(event.data);
// Handle server messages if needed
});
// Handle focus and blur events
window.addEventListener('focus', function() {
socket.send(JSON.stringify({ active: true }));
});
window.addEventListener('blur', function() {
socket.send(JSON.stringify({ active: false }));
});
</script>
sample Debug-node output:
{"payload":"{\"active\":false}","_session":{"type":"websocket","id":"3ab2348f68c3983d"},"_msgid":"69c916af38801171"}
last but not least a flow snippet:
[
{
"id": "dcf88caf4455995d",
"type": "ui_template",
"z": "6f89e794df0518b3",
"group": "0375aefee90144ba",
"name": "WebsocketTemplate",
"order": 4,
"width": 0,
"height": 0,
"format": "<script>\n \n// Create a WebSocket connection\n \nvar socket = new WebSocket('ws://172.16.19.10:1880/tab-state'); \n//if(!window.socket){socket = new WebSocket('ws://172.16.19.10:1880/tab-state')};\n\n// Send the tab's active state when it changes\ndocument.addEventListener('visibilitychange', function() {\n var isActive = !document.hidden;\n socket.send(JSON.stringify({ active: isActive }));\n});\n\n// Handle messages from the server\nsocket.addEventListener('message', function(event) {\n var message = JSON.parse(event.data);\n // Handle server messages if needed\n});\n\n// Handle focus and blur events\nwindow.addEventListener('focus', function() {\n socket.send(JSON.stringify({ active: true }));\n});\n\nwindow.addEventListener('blur', function() {\n socket.send(JSON.stringify({ active: false }));\n});\n</script>",
"storeOutMessages": true,
"fwdInMessages": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 820,
"y": 140,
"wires": [
[]
]
},
{
"id": "919b47275e449b65",
"type": "debug",
"z": "6f89e794df0518b3",
"name": "debug output from websocket",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1350,
"y": 80,
"wires": []
},
{
"id": "e170c5f9f040904f",
"type": "websocket in",
"z": "6f89e794df0518b3",
"name": "",
"server": "d81154f0843a22d0",
"client": "",
"x": 690,
"y": 80,
"wires": [
[
"9fe352d21bee20cc"
]
]
},
{
"id": "9fe352d21bee20cc",
"type": "function",
"z": "6f89e794df0518b3",
"name": "function 1",
"func": "// Create an array to store connected WebSocket clients\nif (!flow.get('clients')) {\n flow.set('clients', []);\n}\n\n// Function to handle new WebSocket connections\nfunction handleNewConnection(connection) {\n // Add the connection to the clients array\n flow.get('clients').push(connection);\n\n // Send a welcome message to the new connection\n connection.send(JSON.stringify({ message: 'Welcome!' }));\n\n // Handle incoming messages from the client\n connection.on('message', function (message) {\n // Process the received message\n var msg = JSON.parse(message);\n\n // Perform actions based on the tab's active state\n // Example: Send the tab's active state to debug output\n node.send({ payload: msg.active });\n });\n\n // Handle WebSocket connection closure\n connection.on('close', function () {\n // Remove the connection from the clients array\n var clients = flow.get('clients');\n var index = clients.indexOf(connection);\n if (index !== -1) {\n clients.splice(index, 1);\n }\n });\n}\n\n// Check if it's a new WebSocket connection\nif (msg.req && msg.req.websocket) {\n // Handle new WebSocket connections\n handleNewConnection(msg.req.websocket);\n}\n\n// Clean up the clients array when the flow is deployed\nnode.on('close', function () {\n flow.set('clients', []);\n});\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 860,
"y": 80,
"wires": [
[
"04bb2080c44cce84"
]
]
},
{
"id": "04bb2080c44cce84",
"type": "switch",
"z": "6f89e794df0518b3",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "cont",
"v": "true",
"vt": "str"
},
{
"t": "cont",
"v": "false",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 1050,
"y": 80,
"wires": [
[
"257f86d240d00c36"
],
[
"4bb335fd3da45565"
]
]
},
{
"id": "257f86d240d00c36",
"type": "delay",
"z": "6f89e794df0518b3",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"allowrate": false,
"outputs": 1,
"x": 1175,
"y": 60,
"wires": [
[
"919b47275e449b65"
]
],
"l": false
},
{
"id": "4bb335fd3da45565",
"type": "delay",
"z": "6f89e794df0518b3",
"name": "",
"pauseType": "rate",
"timeout": "5",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": true,
"allowrate": false,
"outputs": 1,
"x": 1175,
"y": 100,
"wires": [
[
"919b47275e449b65"
]
],
"l": false
},
{
"id": "0375aefee90144ba",
"type": "ui_group",
"name": "Meldungen",
"tab": "9a1ccd72ee604b50",
"order": 2,
"disp": true,
"width": "16",
"collapse": false,
"className": ""
},
{
"id": "d81154f0843a22d0",
"type": "websocket-listener",
"path": "/tab-state",
"wholemsg": "false"
},
{
"id": "9a1ccd72ee604b50",
"type": "ui_tab",
"name": "Meldungen",
"icon": "mi-notifications",
"order": 8,
"disabled": false,
"hidden": false
}
]