Multiple session problem

hi
I have some issuse with msg.socketid
when send notification with msg.socketid
all session recived this notification
what problem its bugged or what

There is no multiple users "problem", as there cannot be multiple users.
Dashboard is single user only. See documentation.

This Dashboard does NOT support multiple individual users. It is a view of the status of the underlying Node-RED flow, which itself is single user. If the state of the flow changes then all clients will get notified of that change.

Messages coming from the dashboard do have a msg.socketid , and updates like change of tab, notifications, and audio alerts will be directed only to that session. Delete the msg.sessionid to send to all sessions.

Hi @bakman2,
Indeed the subject should be "Multiple session problem". But his notification message contains a msg.socketid, so it should only show a notification popup on the dashboard session that is communicating via that socket. Now he sees the same notification on all his sessions, i.e. on all his dashboards.
@d0d04m3: you will need to provide some more information (a.o. that part of your flow), if you want people to be able to assist you...
Bart

2 Likes

Please add a debug node showing what is going into the notification node. Set it to Show Complete Message and post the result here.

2 Likes

thanks to all replay
so
i have tow user login in dashboard
and every user have socket id

so i send msg to this session

Untitled

but all session recived this msg

and other seesion recived too

how to send msg to only one session with socket.id

Messages coming from the dashboard do have a msg.socketid , and updates like change of tab, notifications, and audio alerts will be directed only to that session. Delete the msg.sessionid to send to all sessions.

and it possible to hide or show button at only specified dashboard session ?
exp when click to login only dashboard how clicked button afected not all session show event

1 Like

That session is "your" session that you have created.
If you use a ui_control node - and inspect the whole message you will see this sort of message on connect of page change
image
It is that socketid that is needed to be part of the msg object in order to restrict where it goes back to - so you will need to create a correspondence table between your session and this socketid.

3 Likes

While I'm aware that's an industrial standard to create login systems like this, with node-red not being truly multi user you're potentially creating a security issue, in that users presented with this panel can work their way around through the websocket connection back to Node-RED. Like I said, other industrial aimed tools suffer from similar issues too, I can name a couple from the top of my mind even. But that doesn't mean new tools should still implement the same problems.
I think you need to take back a step and figure out if you really need several users with different access levels, and if so, see if node-red-dashboard is your best solution as it does not currently offer multi-user access, and it will force you to create solutions like this.

5 Likes

yes i known this and Activesocketid generated from this
but nothing work

ok thanks
but now my probleme not for multiuser
its forward msg only to target session

so I need any flow exp to send msg only to session target

Going to this image:

I see two socket IDs listed for your sessions, as you say Session 1 and Session 2. If you follow the blue arrow back to the address bar, you see that it shows a different socket there than it has for session 1 in the data. The browser socket id does however match the Activesocketid. Which specifically are you trying to send/hoping where it would arrive?

1 Like

no this old active session and I am missing to refresh Activesession
and I am use the Ativesession to known how session send me data
so probleme I send msg with socketid target but all session receved msg
and i repeat same process with same Activesession and target session but nothing changed

Is the "Account Login" html in a ui_template node?

I have seen that $scope.$watch('msg', function(msg) { receives all messages from all sessions.

As a test, do this - add a console.log(msg) in $scope watch...

    $scope.$watch('msg', function(msg) {
        console.log(msg);
    })

...then open several sessions - you will see the msg appears in console regardless of session.

If so, then you might need to setup a my_socketid var (to remember your own session ID) on the client side (in the $scope) and ONLY show your custom Dialog if the msg arriving has a matching socketid

@dceejay is there anywhere in $scope object (or somewhere in ui_template @ client side) of accessing the current socketid (without having to somehow send it and store it client side)?

2 Likes

yes I am use ui_template

<div ng-init="init()" id="popup_dialog" class="dialog">
    
    <div class="dialog_content">
        
        <div class="dialog_header">
            <span ng-click="closeDialog()" class="close">&times;</span>
            <h2 class="title">{{payload.title}}</h2>
        </div>
        
        <div class="dialog_body">

            <div layout="column" layout-align="center" style="margin-top: 10px">
                 <h1 class="title">Username:</h1>
                 <md-input-container>
                    
                    <label >{{payload.label1}}</label>
                    <input ng-model="userInput">
                  </md-input-container>
                  <h1 class="title">Password:</h1>
                     <md-input-container>
                         
                    <label>{{payload.label2}}</label>
                    <input type="password" ng-model="passInput">
                  </md-input-container>
         
                 <div layout="row" layout-align="center">
                    <div class="btn_box">
                        <md-button class="btn" ng-click="confirm()">
                            <ng-md-icon icon="done" style="color:#fff;"></ng-md-icon> OK
                        </md-button>
                    </div>
    
                    <div class="btn_box">
                        <md-button class="btn" ng-click="closeDialog()">
                            <ng-md-icon icon="close" style="color:#fff;"></ng-md-icon> Cancel
                        </md-button>
                    </div>
                </div>
            </div> 
          
        </div> <!--dialog_body-->
    </div> <!--dialog_content-->
</div>  <!--dialog-->


<style>

/* The Dialog (background) */
.dialog {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 9999; /* Sit on top */
    left: 0;
    top: 0;
    
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0,0,0); /* Fallback color */
    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
    -webkit-transform: translateZ(0px);
    -webkit-transform: translate3d(0,0,0);
    -webkit-perspective: 1000;
}

.dialog_content {
    position: absolute;
    background-color: #333333;
    left: calc(50% - 170px);
    top: 30px;
    
    margin-top: 8%;
    border-radius: 10px;
    padding: 0;
    width: 340px;
    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19);
    -webkit-animation-name: animatetop;
    animation-name: animatetop;
    animation-duration: 0.4s;
}
h2.title {
    margin:10px;
    font-size: 20px;
}
h1.title {
    margin:10px;
    font-size: 15px;
}
/* Media query for smartphones (to Fix?) */
@media only screen and (min-device-width : 375px) and (max-device-width : 667px) { 
    .dialog_content {
    margin-top: 5%;
    margin-left: 5%;
}
}

/* Add Animation */
@-webkit-keyframes animatetop {
    from {top: -300px; opacity: 0} 
    to {top: 0; opacity: 1}
}

@keyframes animatetop {
    from {top: -300px; opacity: 0}
    to {top: 0; opacity: 1}
}

/* Dialog Header */
.dialog_header {
    padding: 2px 16px;
    background-color: #054649;
    border-radius: 10px 10px 0 0;
    color: #00FFFF;
}

/* Dialog Body */
.dialog_body {
    padding: 5px;
    color: #fff;
}

/* The Close Button */
.close {
    color: #fff;
    float: right;
    font-size: 28px;
    font-weight: bold;
    cursor: pointer;
}

.close:hover,
.close:focus {
    color: #1565C0;
    text-decoration: none;
    cursor: pointer;
}

/* Number container */
.btn_box{
    margin: 5px;
}

/* Buttons style */
.btn {
    min-height: 40px;
    min-width: 80px;
    font-weight: bold;
    margin: 0px 10px 10px 0px;
    box-shadow: 4px 4px 6px 0 #dadada;
    background-color: #054649;
    color: #fff;
}

.btn:not([disabled]):hover {
    background-color: #03A9F4;
}


</style>

<script>

/**
 * Steve-Mcl 2020-03-30
 * Adapated from the excellent work by Daniel Lando, https://github.com/robertsLando
 * to be the basis of a user input popup form
 * Original licence below...
 * *********************************************************************************
 * pin_dialog.js
 * Node-Red UI template for Node-Red Dashboard. 
 * Custom dialog that asks for a PIN to allow actions
 * Enjoy it :). 
 * -- Daniel
 *
 *
 * @license The Unlicense, http://unlicense.org/
 * @version 0.2
 * @author  Daniel Lando, https://github.com/robertsLando
 * @updated 2019-03-18
 * @link    ----
 * **********************************************************************************
 *
 */

var dialog;

/* ==== */
(function(scope) {
    scope.userInput = "";
    scope.passInput = "";
    scope.payload = "";
    scope.topic = "";
    scope.inited = false;
    
    scope.init = function() {
        scope.userInput = "";
        scope.passInput = "";
        //Hide the md-panel
        $('#popup_dialog').parent().parent().css("display", "none");
        dialog = $('#popup_dialog').detach();
    }
    
    scope.showDialog = function() {
        dialog.appendTo(document.body); // better to add the body only when the numpad is displayed (seams to be removed automatically)
        dialog.css("display", "block");
    }
    
    scope.closeDialog = function(){
        scope.userInput = "";
        scope.passInput = "";
        scope.payload = "";
        scope.topic = "";
        dialog.css("display", "none");
    }
    

    scope.confirm = function() {
        scope.send({topic: scope.payload.topic || scope.topic, userInput: scope.userInput, passInput: scope.passInput});
        scope.closeDialog();
    }

    scope.$watch('msg', function(data) {
        if(data && data.topic){
            switch(data.topic){
               case "show":
                   if(scope.inited){
                        scope.topic = data.topic;
                        scope.payload = data.payload;
                        scope.showDialog();
                   }
                   else
                        scope.inited = true;
                break;
                case "close": 
                    scope.closeDialog(); 
                break;
            }
        }
    });
})(scope);

</script>

so I inject console.log(msg) in $scope watch

but cant successful add socketio into scop

Try something like this....

On node-red side, use a ui_control to send a msg with topic "INIT" when a user connects to dashboard.
Then in the client code, when topic == "INIT" store the socketid in $scope

Now when a msg comes in, check that the msg.socketid === $scope.socketid

This is off the top of my head so not 100% sure it'll work but give it a go.

2 Likes

i can release that id
thanks to help

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.