In the previous recipes, we saw a few examples of broadcasting where the sender was always included among the receivers of the message. That was because the APIs we used always included the sender, whether we used the Caller
member, the All
member, or the Group()
method. There are several scenarios though, where it does not make sense to broadcast to the caller; for example, in a live forum application, where it might be enough to broadcast each message to everybody who joined except the sender. That's why SignalR offers the Others
member in order to send calls to everybody but the caller. Let's use it.
Before writing the code of this recipe, we need to create a new empty web application, which we'll call Recipe10
.
This is a simple Hub. To make it work, we need to perform the following steps:
EchoHub
.Startup
, containing the Configuration()
method just calling app.MapSignalR();
to bootstrap SignalR.using System;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
namespace Recipe10
{
[HubName("echo")]
public class EchoHub : Hub
{
public void Hello()
{
var msg = string.Format("Greetings {0}, it's
{1:F}!",
Context.ConnectionId,
DateTime.Now);
var others = Clients.Others;
others.greetings(msg);
}
}
}
What's important here? We need to make sure that we perform the following steps:
Hello()
method, we build a message (msg
) using the current time and the ConnectionId
propertiesmsg
is ready, we use the Clients
member inherited from the Hub type, and from there we take a reference to the Others
property, representing all the currently connected clients and excluding the callergreetings()
method on the others
variable, supplying the msg
object we just built; we expect this call to be performed on all the connected clients except the caller, and to be triggered by each call to the Hello()
method performed by any of themThe client page for this Hub is very simple and it's actually the same as we had in the Broadcasting to all connected clients recipe. Add the following code to this page:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Recipe10</title> <script src="Scripts/jquery-2.1.0.js"></script> <script src="Scripts/jquery.signalR-2.0.2.js"></script> <script src="/signalr/hubs"></script> <script> $(function () { var hub = $.connection.echo; hub.client.greetings = function (message) { var li = $('<li/>').html(message); $('#messages').append(li); }; $.connection.hub .start() .done(function () { $('#send').click(function () { hub.server.hello(); }); }); }); </script> </head> <body> <button id="send">Say Hello!</button> <ul id="messages"></ul> </body> </html>
Let's now open multiple browser windows or tabs pointing to index.html
, and then let's click on the Say Hello! button on them. We will see that all the browser windows receive the same message each time we click on the button, except for the one on which the button has been pressed. The Clients.Others
member is effectively giving us access to the whole set of active connections excluding the one performing the call to the Hub from where we access it, and this gives us a way to broadcast method calls to all of them at once.