Sunday, June 10, 2012

SignalR: finding your clients

As SignalR is all about server-to-client communications, obviously, it's important to be able to find your clients, that your server wants to talk to. There are several scenarios for this, depending on what you're aiming to achieve and are inside a hub, or outside it.
One of the most simple cases, is when your inside a hub and just want to call a method on the client, that just called the server side method - there's a Caller property on the hub object, which gives you a dynamic reference to a calling client, so you can do something like this:
Caller.populateOrders(orders);
If instead you'd like to execute a method on all of your clients, that's also quite easy - just use Clients property on the hub:
Client.removeOrder(id);
What if you want to invoke a method only on a subset of your clients? Well, first, you have to add those clients into specific groups yourself, like this:
// this is how we obtain unique identifier for a current client
string clientId = Context.ConnectionId;
Groups.Add(clientId, "myGroupName1");
// we can add the same client to as many groups as we want
Groups.Add(clientId, "myGroupName2");
And then we can invoke methods on all the clients, belonging to a specific group:
Clients["myGroupName2"].removeOrder(orderId);
Using the same syntax, we can also reach individual clients, by their ID:
Clients[destinationClientConnectionId].privateMessageReceived(message);
This is all nice and easy, as long as you're inside a hub. What if you're not?
First, you need to achieve a reference, to IHubContext object, which then has same properties Clients and Groups, as a Hub object does and youll know what to do from there.
This is fairly simple - just call this static method:
SignalR.GlobalHost.ConnectionManager.GetHubContext();
And this is it - you can now reach all your clients, as if you were in a hub!