Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR - Set ClientID Manually

Tags:

signalr

I want to be able to have individual users send messages to each other using SignalR, therefore I need to send to a Specific Client ID. How can I define the client ID for a specific user at the start of the session - say a GUID Primary Key for the user?

like image 645
reach4thelasers Avatar asked Mar 07 '12 17:03

reach4thelasers


People also ask

Is SignalR ConnectionId unique?

Each client connecting to a hub passes a unique connection id. You can retrieve this value in the Context. ConnectionId property of the hub context.

What is hubName in SignalR?

SignalR Hubs are a way to logically group connections as documented. Take an example of a chat application. A group of users could be part of the same hub which allows for sending messages between users in the group. The hubName here can be any string which is used to scope messages being sent between clients.

How do I stop SignalR connection?

A SignalR connection can end in any of the following ways: If the client calls the Stop method, a stop message is sent to the server, and both client and server end the SignalR connection immediately.


2 Answers

Replace the IConnectionIdFactory with your own https://github.com/SignalR/SignalR/wiki/Extensibility.

Sample usage: http://www.kevgriffin.com/maintaining-signalr-connectionids-across-page-instances/

EDIT: This is no longer supported in the latest versions of SignalR. But you can define a user id for a specific connection using the new IUserIdProvider

like image 71
davidfowl Avatar answered Sep 23 '22 12:09

davidfowl


In SignalR version 1, using the Hubs approach, I override the Hub OnConnected() method and save an association of a .NET membership userId with the current connection id (Context.ConnectionId) in a SQL database.

Then I override the Hub OnDisconnected() method and delete the association between the .NET membership userId and the current connection id. This means, on a page reload, the userId/connectionId association will be up-to-date.

Something along the lines of:

public class MyHub : Hub
{
    private MembershipUser _user
    {
        get { return Membership.GetUser(); }
    }

    private Guid _userId
    {
        get { return (Guid) _user.ProviderUserKey; }
    }
    
    private Guid _connectionId
    {
        get { return Guid.Parse(Context.ConnectionId); }
    }

    public override Task OnConnected()
    {
        var userConnectionRepository = new UserConnectionRepository();
        userConnectionRepository.Create(_userId, _connectionId);
        userConnectionRepository.Submit();

        return base.OnConnected();
    }

    public override Task OnDisconnected()
    {
        var userConnectionRepository = new UserConnectionRepository();
        userConnectionRepository.Delete(_userId, _connectionId);
        userConnectionRepository.Submit();

        return base.OnDisconnected();
    }
}

Then when I need to trigger a SignalR event for a specific user, I can work out the connectionId from the database association(s) with the current userId - there may be more than one association if multiple browser instances are involved.

like image 26
Richard Pursehouse Avatar answered Sep 22 '22 12:09

Richard Pursehouse