Yusuf Uzun
Yusuf Uzun

Reputation: 1511

How can I design better communicate between application members and Web API and Signalr Hubs

I am working in a project which needs to communicate with users realtime. Basically I am following "synchronize pages over web api" path which is introducing in this video (also Brad Wilson has a nice video like this one) and the repository here for video.

My question is about mapping application members with their ConnectionIds which is producing by Signalr.

I used to be saving every signalr connection ID in a database table like:

ConnectionID

MemberID

ConnectionStatusID --> Connected(1), Disconnected(2), Reconnecting(3)

I was fetching member's connection IDs in most requests.

Then I decided to change this design. Now I am grouping every member with a unique string when OnConnected and OnDisconnected like this:

public override Task OnConnected()
{
    Groups.Add(this.Context.ConnectionId, string.Format("MyHub_{0}",HubUser.MemberID));
    return base.OnConnected();
}

public override Task OnDisconnected()
{
    Groups.Remove(this.Context.ConnectionId, string.Format("MyHub_{0}",HubUser.MemberID));
    return base.OnConnected();
}

Now I am not fetching anything from database about member connection IDs. It is only working over Web API for making synchronization between browser tabs.

I simply show how I am handling incoming Request and using Hub in Web API:

public HttpResponseMessage Example()
{
    string msg = "Example to all";
    //some other process

    //Hub is an instance of a IHubContext

    Hub.Clients.Group(string.Format("MyHub_{0}", HubUser.MemberID)).example(msg);

    return Request.CreateResponse(HttpStatusCode.OK, msg);
}

So which one do you think is efficient way for using Signalr. What would you suggest is possibly better than these. Is making a dependency between hub and WebApi is a good design choice to go.

And also project will be deployed to multiple servers and Load Balancer will work in front of them (I am going to use Sql Backplane for this). There are few projects which must talk to Web API, indirectly to hub too.

Upvotes: 1

Views: 445

Answers (1)

halter73
halter73

Reputation: 15234

I like your second solution as it should require less DB queries. It is no less efficient for SignalR to send to a group than it is for it to send to a connection id. You just need to ensure your group names (HubUser.MemberID) are unique and non-spoofable.

In SignalR 2.0, we make this pattern even easier: http://www.asp.net/signalr/overview/signalr-20/hubs-api/mapping-users-to-connections#IUserIdProvider

If your users' MemberIDs match up with their IPrincipal.Identity.Name, then you can just change all your code to use Clients.User(HubUser.MemberID)....

If you don't want to base your SignalR user id on the request's IPrincipal, you can provide your own IUserIdProvider and inject it using SignalR's dependency resolver.

http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection

Upvotes: 1

Related Questions