locked
SignalR UserConnected always shows last user to connect, instead of current RRS feed

  • Question

  • User1080340250 posted

    I have a specific page on my site whee, when a user clicks on a Tab, I want to add them to the Group (RecordId for this page).  I want a Notification sent to anyone else in that Group.  When I test the below, it says 'Tim has joined the Group'.  When I open a 2nd, Incognito tab and re login (using Identity), it says 'Tim has joined the group', if I refresh, it then says, 'The new Name I chose has joined the Group'. 

    When someone logs in, I saved their UserId in a BaseModel so it gets passed to the UI in a hidden field on every call.

    my Tab click 

       Messenger($("#Id").val());

    My .js File

    function Messenger(id) {
    
        "use strict";
    
        var groupName = $("#Id").val();
        var SubmittedBy = $("#User_Id").val();
        var UserName = $("#UserName").val();
    
        var connection = new signalR.HubConnectionBuilder()
            .withUrl("/MessageHub")
            .build();
    
        connection.on("Connected", function (message) {
            Toast.fire({
                icon: 'success',
                title: message
            });
        });
    
        connection.on("UserConnected", function (connectionId) {
            //User has joined the group
            connection.invoke("JoinGroup", groupName, UserName).catch(function (err) {
                return console.error(err.toString());
            });
        });
    
    $(document).on("click", '.ButtonSend', function () {
    
            var groupName = $("#Id").val();
            var SubmittedBy = $("#User_Id").val();
    
            var ctl = this.id;
    
            var id = ctl.split('_')[1];
    
            var message = $('#ButtonSendMessage_' + id).val();
    
            if (js.utils.CheckisEmpty(message) === true) {
                Toast.fire({
                    icon: 'error',
                    title: 'Cannot Submit Empty Message'
                })
            } else {
                try {
                    connection.invoke("SendMessageToGroup", groupName, message, id, SubmittedBy).catch(function (err) {
                        return console.error(err.toString());
                    });
                    event.preventDefault();
                }
                catch (e) {
                    console.error(e.toString());
                }
                event.preventDefault();
            }
    
        });


    connection.on("UserDisconnected", function (connectionId) { //User has UserDisconnected the group }); connection.start().catch(function (err) { return console.error(err.toString()); }); }

    My MessageHub

            public Task SendMessageToAll(string message)
            {
                return Clients.All.SendAsync("ReceiveMessage", message);
            }
    
            public Task SendMessageToCaller(string message)
            {
                return Clients.Caller.SendAsync("ReceiveMessage", message);
            }
    
            public Task SendMessageToUser(string connectionId, string message)
            {
                return Clients.Client(connectionId).SendAsync("ReceiveMessage", message);
            }
    
            public async Task JoinGroup(string groupName, string UserName)
            {
                await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
                await Clients.Group(groupName).SendAsync("Connected", $"{UserName} has joined the group.");
            }
    
            public async Task<Task> SendMessageToGroup(string groupName, string message, string id, string SubmittedBy)
            {
                var user = await Business.User.Get(Convert.ToInt32(SubmittedBy));
    
                return Clients.Group(groupName).SendAsync("ReceiveMessage", message, id, user);
            }
    
            public override async Task OnConnectedAsync()
            {
                await Clients.All.SendAsync("UserConnected", Context.ConnectionId);
                await base.OnConnectedAsync();
            }
    
            public override async Task OnDisconnectedAsync(Exception ex)
            {
                await Clients.All.SendAsync("UserDisconnected", Context.ConnectionId);
                await base.OnDisconnectedAsync(ex);
            }

    Wednesday, January 27, 2021 7:42 PM

All replies

  • User-939850651 posted

    Hi Tim Cadieux,

    According to the code you provided, I use these code and create a simple demo.

    But you haven't posted the complete code (for example, invoke SendMessageToGroup), so I can't fully reproduce your problem.

    Something like this:

    document.getElementById("sendButton").addEventListener("click", function (event) {
                var SubmittedBy = document.getElementById("User_Id").value;
                var message = document.getElementById("messageInput").value;
                connection.invoke("SendMessageToGroup", groupName, message, SubmittedBy).catch(function (err) {
                    return console.error(err.toString());
                });
            });

    var user = await Business.User.Get(Convert.ToInt32(SubmittedBy));

    What is the Business in this code part, a collection of users? I see that you filter users through the SubmittedBy property, and I guess this value may remain on the page, which causes the problem.

    If possible, please post the relevant complete code so that we can reproduce the problem, which will help us find the cause of the problem and solve it.

    Best regards,

    Xudong Peng

    Thursday, January 28, 2021 9:00 AM
  • User1080340250 posted

    Sorry, I didn't think that function was pertinent, I've edited the Post and added it.

    For the Business.User call...I get the Full Model for the current User and pass it back to the Message, just so i can have the Photo and the name of the user attached...

    Thursday, January 28, 2021 4:37 PM
  • User-939850651 posted

    Hi Tim Cadieux,

    I saw that you mentioned that you are using user identity to implement authentication, and you have a page refresh operation. Did you use the only browser for testing?

    If this is the case, when you log in as a new user in the same browser, the browser will update the user's identity information to the last logged in user.

    You should test it with different browsers.

    Best regards,

    Xudong Peng

    Friday, January 29, 2021 2:49 AM
  • User1080340250 posted

    Yes i was using with Incognito mode, also, this occurs when multiple users login.

    Is there possibly a simple working example somewhere I can look at?  Most of the examples I find are for React or Angular...

    Friday, January 29, 2021 1:57 PM
  • User-939850651 posted

    Hi Tim Cadieux,

    Is there possibly a simple working example somewhere I can look at?  Most of the examples I find are for React or Angular...

    The user identifier for a connection can be accessed by the Context.UserIdentifier property in the hub.

    You could also refer to this document below.

    https://docs.microsoft.com/en-us/aspnet/core/signalr/groups?view=aspnetcore-5.0

    Best regards,

    Xudong Peng 

    Monday, February 1, 2021 10:08 AM