Similar to what we just did in order to exclude specific connections from the set of all the connected clients, we can provide exceptions in the context of a specific group. We can broadcast to all the connections in a given group, excluding a list of specific ConnectionId
values that we want to omit.
Before writing the code of this recipe, we create a new empty web application, which we'll call Recipe12
.
Let's prepare our project by performing the following steps:
EchoHub
.Startup
, with a Configuration()
method calling app.MapSignalR()
.using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
namespace Recipe12
{
[HubName("echo")]
public class EchoHub : Hub
{
public void Subscribe(string groupName)
{
Groups.Add(Context.ConnectionId, groupName);
}
public void Hello(string groupName)
{
var msg = string.Format("Welcome from {0}",
groupName);
var targets = Clients.Group(groupName,
Context.ConnectionId);
targets.greetings(msg);
}
}
}
What's important here? We need to make sure that we perform the following steps:
Subscribe()
method that receives a groupName
parameter and then uses the Groups
member inherited from Hub
to add ConnectionId
of the caller inside a group called as specified, using the Add()
method.Hello()
method builds a message (msg
) and then it uses the Group()
method of the Clients
member exposed by Hub to broadcast the message to all the connections belonging to the groupName
group; we are also supplying an additional parameter (ConnectionId
of the caller) to exclude the calling client from the broadcast.Group()
method accepts a variable length for the list of connection identifiers to be excluded. Here, we are specifying just one value, but we can supply many of them. Also, for simplicity, we are using ConnectionId
of the caller itself to set an exclusion, but any other connection identifier would also work.OthersInGroup
, which would have been in fact a better match for this specific case; however, the goal here was to illustrate the generic case of the exclusion of any connection from a group. Whenever you need to specifically exclude the caller, OthersInGroup
will be your best friend.Let's write a client to test what we wrote inside the Hub. This client is incidentally exactly the same as the index.html
page that we wrote for the Adding a connection to a group recipe. Therefore, we will keep the comments to a minimum. The following code should be used:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Recipe12</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 () { $('#subscribe').click(function () { $(this).toggle(); var v = $('#group').val(); hub.server.subscribe(v); $('#send').click(function () { hub.server.hello(v); }); $('#send').toggle(); }); }); }); </script> </head> <body> <label>Group:</label> <select id="group"> <option value="A">A</option> <option value="B">B</option> <option value="C">C</option> </select> <button id="subscribe">Subscribe</button> <button id="send" style="display: none">Say Hello!</button> <ul id="messages"></ul> </body> </html>
This client allows the user to subscribe to a specific group and to broadcast messages that will be received only by other connections subscribed to the same group as the sender. The specific exclusion logic is completely server-side based, as we already explained while commenting the code from EchoHub
.
We're ready to run index.html
multiple times in different browser windows or tabs, and we'll then click on the Subscribe button on each window after selecting one of the three available groups. After that, we'll be allowed to click on the Say Hello! button on any of the browser windows, and we'll see the following things happen: