Broadcasting to all clients in a group except the caller

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.

Getting ready

Before writing the code of this recipe, we create a new empty web application, which we'll call Recipe12.

How to do it…

Let's prepare our project by performing the following steps:

  1. We add a Hub called EchoHub.
  2. Let's then add the usual OWIN Startup class named Startup, with a Configuration() method calling app.MapSignalR().
  3. Let's edit Hub's content using the following code:
    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:

  • We first expose a 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.
  • The 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.
  • The 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.
  • Since SignalR 2.0, we have a new API called 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:

  • Each hit on the Say Hello! button will send a message only to the windows that have subscribed to the same group as the one where the button was clicked on, excluding the window of the caller.
  • Each window will receive messages only from other windows that have subscribed to the same group as that of the target window.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.36.141