# Session, dashboard concurrent use

**URL:** <https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265>\
**Category:** General\
**Tags:** uibuilder\
**Created:** [28 November 2023 22:10 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265 "2023-11-28T22:10:01Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [28 November 2023 22:10 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/1 "2023-11-28T22:10:02Z")

</div>

I know there has been a few posts on multi users in dashboard, but my problem is not exactly the same (I hope).

Let's say I have a bunch of sensors, all send the same data structure. I want to create a dashboard tab, where data from a sensor is displayed.

I want to use the same dashboard tab to display data from sensor 1, but if I open it in another browser tab, I want to see sensor 2.

So far what I understood that I can place a ui-control and it will give me messages when a user opens my tab. And I guess I can keep this information in the context and store which socketid is viewing which sensor. And before I refresh the data on the UI I can pick which sensor's data to show. Would this result in the same dashboard showing different information on the same tab?

Also, would it be possible for me to pass the sensor ID in the dashboard URL? Like `http://<ip>:1880/ui/#!/2?sensorid=2`  
Is there a `req.param` for the dashboard URL request?

Thanks,  
Csongor

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [28 November 2023 22:23 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/2 "2023-11-28T22:23:40Z")

</div>

> [@nygma2004](#):
>
> which socketid is viewing which sensor

Note that the sessionid can change quite easily. It only takes a temporary disconnection for it to change and this can happen if the user leaves the PC for a while or on some other network interruption.

Also note that you would probably need to use some front-end custom code in a ui\_template to be able to differentiate things.

Really, uibuilder is better at handling these things as it already has filters you can use for page names, client ids and browser tab ids. all of which are more stable.

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [28 November 2023 22:34 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/3 "2023-11-28T22:34:08Z")

</div>

OK, I have modest experience with ui-builder. Although I don't think I used client id and browser id information before. How can I access that?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [29 November 2023 01:29 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/4 "2023-11-29T01:29:15Z")

</div>

If you look at the connect control msg when a client connects, you should see that it reports the page name, client id and tab id.

If you include one or more of those in a msg to send to uibuilder in, for example `msg._uib.clientId` or `msg._ui.clientId`, any connected clients will check those and will only accept the msg if the property matches.

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [29 November 2023 18:14 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/5 "2023-11-29T18:14:29Z")

</div>

Can you elaborate on this? I created a test uibuilder node, and I am sending data in with `msg._uid.clientId` with a client id of my connected client and also with some random client id. All of them are being processed by the uibuilder (message shows up on the template page). Do you mean that in `uibuilder.onChange` I should validate if the value of `msg._uid.clientId` matches with the current client ID? How do I get the client ID in the index.js?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [29 November 2023 19:35 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/6 "2023-11-29T19:35:15Z")

</div>

> [@nygma2004](#):
>
> \_uid

`_uib` not `_uid`

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [29 November 2023 20:53 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/7 "2023-11-29T20:53:28Z")

</div>

Sorry, typo, I used \_uib:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/6/560e60eda250821cfe219a2e746791fcbe4b33fb.png)  
This is one of the inject node that matches the clientID I got from uibuilder and the other inject node users some random different \_uib. And I can see both messages on the UI.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [30 November 2023 12:26 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/8 "2023-11-30T12:26:39Z")

</div>

> [@TotallyInformation](#):
>
> msg.\_uib.clientId

Apologies for the delay.

I've just tested this and I got the expected result, a message containing the correct clientId gets through and a different clientId does not.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/9/99d27062ed8b9884a11bc2f4020f338dd265d68c.png)

`tabId` filtering also works as expected.

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/b/db870bf6a9ee05ea901320f8305b3f208d0c54c1.png)

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [30 November 2023 20:35 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/9 "2023-11-30T20:35:55Z")

</div>

OK, as we discussed on the other topic, this could be down to the fact that I am still on version 5.1.1, since I seem to have done the same from your screenshot above.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [30 November 2023 21:00 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/10 "2023-11-30T21:00:24Z")

</div>

Ah, I missed that. The filters were added in v6.5

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [20 January 2024 22:58 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/11 "2024-01-20T22:58:19Z")

</div>

OK, since the last post, I did upgrade to the latest version but it is still not working:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/5/951ca0a0c8dd7c68197159a52d4b08fc52f61002.png)  
The clientId you can see on the screen is clearly a bogus ID, but the message is still shown in the uibuilder. So I am still missing something.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [20 January 2024 23:25 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/12 "2024-01-20T23:25:05Z")

</div>

I'll try to check it out tomorrow.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [21 January 2024 15:56 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/13 "2024-01-21T15:56:54Z")

</div>

Just tested again.

Opened up the same page in 2 different browsers, found their clientIds and set up two inputs sent direct to the uibuilder node.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/2/5251b9d7c67462ba971ccf6d21a19b809f531723.png)

With the other input having the other clientId. Each browser window only shows the message for the correct client.

Can you share the HTML you are using?

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [21 January 2024 17:06 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/14 "2024-01-21T17:06:06Z")

</div>

Sorry, you are right. I started this example with 5.x.x uibuilder, and the HTML must have been creaed with that example. I deleted the uibuilder node, recreated it and it works fine now.

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [21 January 2024 18:21 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/15 "2024-01-21T18:21:05Z")

</div>

I extended the logic beyond the simple inject nodes, so Node-Red registers all clients that are connected to it can tag the traffic to the correctionding session id. But what I noticed, that I open the same uibuilder page on multiple tabs in Chrome, or separate Chrome windows, the clientid is always the same. I though those would differ for each instance. Or is that the \_socketid?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [21 January 2024 19:38 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/16 "2024-01-21T19:38:16Z")

</div>

> [@nygma2004](#):
>
> But what I noticed, that I open the same uibuilder page on multiple tabs in Chrome, or separate Chrome windows, the clientid is always the same. I though those would differ for each instance. Or is that the \_socketid?

Sorry, I probably made it more complex than maybe it needed to be. But I wanted to be able to identify a "person" reasonably accurately without having to do a lot of complex stuff. So I decided that a "client" is _any tab on the same browser_ until that browser restarts (or clears cookies).

If you want to identify a single tab, you can use the `tabId` for that.

You can, of course, identify the page instead or as well as. And you should be able to combine them.

While the `_socketId` identifies a specific [socket.io](http://socket.io) connection (an individual tab in our case), it is not really very reliable because it changes if the user reloads the page or if the connection is temporarily lost (e.g. a network blip or the browser tab or PC going to sleep). So I generally recommend avoiding it in most cases.

* * *

BTW, in a future release, it will probably be possible for 1 client id, tab id, and/or page name to talk to another via Node-RED just by knowing the appropriate Id. I'm still playing around with [Socket.IO](http://Socket.IO)'s rooms features to see what is actually feasible and sensible to do.

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [21 January 2024 19:58 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/17 "2024-01-21T19:58:57Z")

</div>

For me even thet `tabid` are the same if I duplicate the window in Chrome.  
Actually, I would not mind the `_socketid` as long as I can also pass it to the `msg._uib` parameter, or something similar. Also just a question, I assume if I assume `msg._uib` and pass that through `uib-element` that is still fine.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [21 January 2024 20:31 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/18 "2024-01-21T20:31:23Z")

</div>

> [@nygma2004](#):
>
> For me even thet `tabid` are the same if I duplicate the window in Chrome.

Ah, I didn't know that! If you navigate to the same page with a new tab, you get a new id but if you duplicate it you get the same tab id. ☹

> [@nygma2004](#):
>
> Actually, I would not mind the `_socketid` as long as I can also pass it to the `msg._uib` parameter, or something similar.

All you need for that is to have `msg._socket` (not `msg._uib._socket`) in the msg you try to send to the uibuilder node. In that case, it will automatically only go to the appropriate client.

---

<div class="post-metadata">

**Author:** ![nygma2004](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nygma2004/32/1308_2.png) [@nygma2004](https://discourse.nodered.org/u/nygma2004)\
**Post date:** [21 January 2024 20:43 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/19 "2024-01-21T20:43:09Z")

</div>

Let me leave my example here. Still does not seem to work with `_socket`.  
There is a "Client Collection" function node which logs which client has which socket id, and link it to the `?device=test1` or `?device=test2` in the URL parameter.  
Based on this, the "Router" function node adds `msg._socket` to the outgoing message before sending it through the uib-element. I checked the message leaving uib-element, and each has the correct \_socket id. But still each message Chrome instance gets the message. I must be missing something simple.

```auto
[{"id":"ddf27e1052787ad5","type":"debug","z":"b4d7bc8a9540f906","name":"debug 72","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1040,"y":120,"wires":[]},{"id":"e181aa0641a3733f","type":"debug","z":"b4d7bc8a9540f906","name":"debug 73","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1040,"y":260,"wires":[]},{"id":"c545de0744ed3c75","type":"function","z":"b4d7bc8a9540f906","name":"Test 1","func":"let number = Math.floor(Math.random()*100);\nmsg.topic = \"test1\";\nmsg.payload = number;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":220,"wires":[["9e9cbe1ba459dfc1"]]},{"id":"bb23d9df851b734e","type":"inject","z":"b4d7bc8a9540f906","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"_uib","v":"{\"clientId\": \"eqQ9-YhGOxeAtcv2Etc5i\" }","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"test","payload":"OK","payloadType":"str","x":470,"y":340,"wires":[["958d1f8c4fc837f6"]]},{"id":"01512afde4d3dcf2","type":"inject","z":"b4d7bc8a9540f906","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"},{"p":"_uib","v":"{\"clientId\": \"fdfdfdfdfdffsfsd\" }","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"test","payload":"Not OK","payloadType":"str","x":490,"y":380,"wires":[["958d1f8c4fc837f6"]]},{"id":"958d1f8c4fc837f6","type":"uibuilder","z":"b4d7bc8a9540f906","name":"","topic":"","url":"uitest","okToGo":true,"fwdInMessages":false,"allowScripts":false,"allowStyles":false,"copyIndex":true,"templateFolder":"blank","extTemplate":"","showfolder":false,"reload":false,"sourceFolder":"src","deployedVersion":"6.8.2","showMsgUib":false,"title":"","descr":"","x":780,"y":220,"wires":[["ddf27e1052787ad5"],["e181aa0641a3733f","3bb6fe2cc8712d87"]]},{"id":"08a6f1d386d371a7","type":"inject","z":"b4d7bc8a9540f906","name":"Toggle Visible Msgs","props":[{"p":"_uib","v":"{\"command\":\"showMsg\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":510,"y":420,"wires":[["958d1f8c4fc837f6"]]},{"id":"3bb6fe2cc8712d87","type":"function","z":"b4d7bc8a9540f906","name":"Client collection","func":"let clientlist = flow.get(\"clientlist\");\nif (clientlist === undefined) {\n clientlist = {};\n}\n\nif (msg.uibuilderCtrl === \"client connect\") {\n if (msg.urlParams.device !== undefined) {\n clientlist[msg.urlParams.device] = msg._socketId;\n }\n // return because the URL is missing the device parameter\n delete msg.uibuilderCtrl;\n return msg;\n}\nif (msg.uibuilderCtrl === \"client disconnect\") {\n delete clientlist[msg.urlParams.device];\n}\nflow.set(\"clientlist\", clientlist);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1060,"y":320,"wires":[["e6824a35d4e387b0"]]},{"id":"f9de99c97f05389e","type":"inject","z":"b4d7bc8a9540f906","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"1","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":130,"y":180,"wires":[["c545de0744ed3c75","b3f3614223dfa819"]]},{"id":"b3f3614223dfa819","type":"function","z":"b4d7bc8a9540f906","name":"Test 2","func":"let number = Math.floor(Math.random()*100+100);\nmsg.topic = \"test2\";\nmsg.payload = number;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":260,"wires":[["9e9cbe1ba459dfc1"]]},{"id":"9e9cbe1ba459dfc1","type":"function","z":"b4d7bc8a9540f906","name":"Router","func":"let clientlist = flow.get(\"clientlist\");\nif (clientlist === undefined) {\n return;\n}\n\nif (clientlist[msg.topic] !== undefined) {\n msg._socket = clientlist[msg.topic];\n return msg;\n}\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":240,"wires":[["30674faded2349bf"]]},{"id":"30674faded2349bf","type":"uib-element","z":"b4d7bc8a9540f906","name":"","topic":"","elementtype":"html","parent":"#more","parentSource":"","parentSourceType":"str","elementid":"more","elementId":"","elementIdSourceType":"str","heading":"","headingSourceType":"str","headingLevel":"h2","data":"payload","dataSourceType":"msg","position":"last","positionSourceType":"str","passthrough":false,"confData":{},"x":1050,"y":460,"wires":[["958d1f8c4fc837f6","f1923e4c384ac61a"]]},{"id":"e6824a35d4e387b0","type":"change","z":"b4d7bc8a9540f906","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"<p>Missing device parameter in the payload</p>","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":810,"y":460,"wires":[["30674faded2349bf"]]},{"id":"f1923e4c384ac61a","type":"debug","z":"b4d7bc8a9540f906","name":"debug 81","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1230,"y":500,"wires":[]}]

```

test1 and test2 just random numbers, but test2 is always \>100, test1 \<100. Therefore I expect the window to show different numbers.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [22 January 2024 16:54 UTC](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265/20 "2024-01-22T16:54:28Z")

</div>

Had a quick play with that flow last night. I was a bit too tired to make full sense of it. However, I think you have a small logic error which is causing the issue. But I need to go through step by step to work it out.

[Next page](https://discourse.nodered.org/t/session-dashboard-concurrent-use/83265.md?page=2)
