July 2014

Presented by Steven Salat

# Wat? * Library that simplifies real-time communication * Handles transports, cross-browser compatibility, etc * Think "_push_" and Remote Procedure Calls * Part of [Microsoft ASP.NET]( * Open [source]( meaning you can contribute * Host it in IIS or a [standalone application](
# When? You can use SignalR for anything but some examples include * Chat rooms * Multi-player games * Notification systems * Pushing Δ changes for data * Pushing Δ changes for code
Take it from Doge ![signalr-doge](signalr-doge.png)
# How? A SignalR connection starts as HTTP, and is then promoted to a WebSocket connection if it is available. Otherwise a fallback such as Forever Frame or AJAX Long Polling is used transparently. Note that both the server and client must support the transport for it to selected.
# Hub A Hub is a high-level pipeline that allows your client and server to call methods on each other directly as easily as you would call a local method. Complex parameters are serialized and deserialized as expected during method invokation. Hubs use their own protocol on top of sockets so you don't have to worry about how it happens, it just works.
# Server Code ```cs using System; using System.Web; using Microsoft.AspNet.SignalR; namespace SignalRChat { public class ChatHub : Hub { // Public methods can be called by any client connected to this hub public void Send(string name, string message) { // Call the broadcastMessage method on all connected clients Clients.All.broadcastMessage(name, message); } } } ``` [Source Code](
# Client Code ```html <body> <input type="text" id="message" /> <input type="button" id="sendmessage" value="Send" /> <input type="hidden" id="displayname" /> <ul id="discussion"></ul> <script src="Scripts/jquery-1.10.2.min.js"></script> <script src="Scripts/jquery.signalR-2.1.0.min.js"></script> <script src="signalr/hubs"></script> <!--autogen...only required for proxy--> <script type="text/javascript"> // Declare a proxy to reference the hub. var chat = $.connection.chatHub; // Create a function that the hub can call to broadcast messages. chat.client.broadcastMessage = function (name, message) { // Add the message to the page. $('#discussion').append('<li><b>' + name + '</b>:' + message + '</li>'); }; // Get the user name and store it to prepend to messages. $('#displayname').val(prompt('Enter your name:', '')); // Start the connection. $.connection.hub.start().done(function () { $('#sendmessage').click(function () { // Call the Send method on the hub. chat.server.send($('#displayname').val(), $('#message').val()); // Clear text box and reset focus for next comment. $('#message').val('').focus(); }); }); </script> </body> ```
# Groups Groups are subsets of connected clients. Simply add a connection id to a group name. If the group does not exist, it will be created. Removing the last connection from the group will delete the group. Think of groups like _tags_ on a blog post or _labels_ in gmail.
# Caveats Unfortunely, there is no API for getting a group membership list or a list of groups in order to maximize scalability. If you need group membership, you must store your own data structure in addition to calling Group.Add() and Group.Remove() methods.
# Group Code ```c# // Method in the Hub public async Task JoinRoom(string userName, string roomName) { await Groups.Add(Context.ConnectionId, roomName); // Send message to all clients in this group (including calling client) Clients.Group(roomName).addChatMessage(userName + " joined."); } ``` Alternative ways to message the clients ```c# // Send message to all clients Clients.All.addChatMessage(name, message); // Send message to all clients except conId1 and conId2 Clients.AllExcept(conId1, conId2).addChatMessage(name, message); // Send message to calling client only Clients.Caller.addChatMessage(name, message); // Send message to all clients in group except conId1 and conId2 Clients.Group(groupName, conId1, conId2).addChatMessage(name, message); // Send message to all clients except the calling client Clients.OthersInGroup(groupName).addChatMessage(name, message); ```
# Cons * WebSocket transport requires the server use Windows Server 2012 or Windows 8, and .NET Framework 4.5 * IIS on Windows 7 has a built in limitation of 10 concurrent connections * Chrome Frame can cause problems (fix in next version?)
# Demo * [Chat Example]( * WDITR 4.0 field locking