SignlaR multi user live chat desynchronisation

I have a live chat in which multiple people would be connected simultaneously. All public messaging works fine, but sometimes private messaging to a specific id doesn’t work. I believe i narrowed it down to when people disconnected and reconnected that they connected to a different instance (perhaps IIS had recycled and started a new hub).
I thought I had fixed it, but I haven’t and now I’m here because I’m stuck. What I thought would fix it was changing the connection variable within the startChat() function to refresh it with the correct information.
This is a cut down version of the code, as I didnt thing the rest would be necesary.

Issue is that when connected to signalR recipients of a message directly to them doean’t come through, even though the chat Id it’s being sent to it correct. Possible hub/socket mismatch?

var chat = $.connection.chatHub;

$(document).ready(function () {
    // Start the chat connection.
    startChat();

    //restart chat if disconnected
    $.connection.hub.disconnected(function () {
        setTimeout(startChat(), 5000);
    });

    $.connection.hub.error(function (error) {
        $('#messagebar').html('Chat ' + error + '. If this message doesn\'t go away, refresh your page.');
    });

    chat.client.addToChat = function (response) {
        $('#chat-' + response.Type).prepend(response.Message);
    };
});

function startChat() {
    chat = $.connection.chatHub;
    $.connection.hub.start().done(function () {
        //get recent chat from db and insert to page.
        //also saves user's chat id to their user for lookup when private messaging
        $.ajax({
            method: 'POST',
            url: '/api/Chat/SetupChat/'
        });

        $('#messagebar').html('Connected to chat.');
    });
}

Any help appreciated, Thanks.

1 thought on “SignlaR multi user live chat desynchronisation”

  1. Not sure exactly how your message is going missing, but you should send messages to a User instead of by connection id. This way you be able to identify on the server that a User has at least one connection, and send messages to all connections for that User. if a given connection id is no longer valid, but another one is (because the client has refreshed the page for example) the message wont be lost.

    From the docs https://docs.microsoft.com/en-us/aspnet/core/signalr/groups:

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

    public Task SendPrivateMessage(string user, string message)
    {
        return Clients.User(user).SendAsync("ReceiveMessage", message);
    }
    

    Not sure how this relates exactly to your server code, but you could add it if you’re unclear how to progress.

    Reply

Leave a Comment