ict.ken.be

Delivering solid user friendly software solutions since the dawn of time.

SignalR - Notes

Categories: .Net Javascript

Real-time Web & Push Services with Hubs
by Christian Weyer (christian.weyer@thinktecture.com)
Developers of SignalR on https://jabbr.net

Push Services pattern (models a service that) 

  • accepts incoming connections from callers
  • is able to push data down to callers
  • abstracts from communication nitty-gritty details
  • consumers send to push service
  • push service notifies consumers
  • external events (Db, Message Queue, ...) trigger push service

HTTP is the protocol

  • Periodic Polling
  • Long Polling (http streaming/comet) -> server only responds when there is data
  • Forever Frame (connection within an iframe)
  • Server-Sent Events (SSE)
  • Web Sockets (only Windows 8/Server 2012, network considerations/blockings)

Hubs

  • public methods are callable from the outside
  • send messages to clients by invoking client-side methods
  • [HubName("chat")]
  • Context holds connection- and request-specific information
  • ConnectionId, Request, Headers, RequestCookies, QueryString, User
  • First register the hubs and then add your other routes.
  • Target method with parameters is dynamically 'injected' into code path, serialized, and embedded into protocol response
  • Groups are not persisted on the server
  • We need to keep track of what connections are in chat groups
  • No automatic group count 
Clients.Caller.newMessage(message);
Clients.Client(Context.ConnectionId).newMessage(message);
Clients.All.newMessage(message);
Clients.Others.newMessage(message);
Clients.AllExcept(Context.ConnectionId).newMessage(message);

Groups.Add(Context.ConnectionId, room);
Clients.Group(room).newMessage(msg);

public override Task OnConnected() {}
public override Task OnDisconnected() {}
public override Task OnReconnected() {}

// Sending data from outside a hub, retrieve hub context via dependency resolver
private void SendMonitorData(string eventType, string connection)
{
var context = GlobalHost.ConnectionManager.GetHubContext<MonitorHub>();
context.Clients.All.newEvent(eventType, connection);
}

Clients

  • .NET4.0+, WinRT, Windows Phone 8, Silverlight 5, jQuery, C++, iOS native, iOS via Mono, Android via Mono
  • /signalr/hubs is the dynamic proxy contract
  • use signalr.exe ghp /url:http://localhost:31373 tool to create a static proxy

Javascript with proxy

 $.connection.hub.logging = true;
chat = $.connection.chat
$.connection.hub.start({ transport:'longPolling' });
$.connection.hub.connectionSlow = onConnectionSlow;

Javascript without proxy

var connection = $.hubConnection();
var proxy = connection.createHubProxy('chat');
proxy.on('newMessage', onNewMessage);
connection.start();
proxy.invoke('sendMessage', $('#message').val());

.Net

var hubConnection = new HubConnection("http://localhost/ps");
var chat = hubConnection.CreateHubProxy("chat");
chat.On<string>("newMessage", msg => messages.Invoke(new Action(() => messages.Items.Add(msg));
hubConnection.Start().Wait();
// Opened, Closed, Error, Received, Reconnected, Reconnecting, StateChanged

Hosting

OWIN (Open Web Server Interface for .Net) - http://owin.org
Katana project - http://katanaproject.codeplex.com

  • Application delegate (AppFunc) var AppFunc = Func<IDictionary<string, object>, Task>;
  • Environment dictionary
  • ASP.Net hosting sits on top of OWIN
  • Self-hosting
  • Microsoft.Owin.Hosting aka Katana
  • Microsoft.Owin.Host.HttpListener
// process user needs http.sys permissions on the url namespace
public void Configuration(IAppBuilder app)
{
var a = Assembly.LoadFrom("Services.dll");
app.MapHubs(new HubConfiguration { EnableCrossDomain = true });
}

using(WebApplication.Start<Startup>("http://localhost:6789")
{
Console.WriteLine("Hubs running...");
Console.ReadLine();
}

// jQuery client needs to explicitly set connection url
$.connection.hub.url = "http://localhost:6789/signalr";

Azure

  • Which server instance handles the client request?
  • Which instance pushes?

Other aspects

  • Use SignalR message bus
  • SignalR extensible architecture
  • Persistent connections
  • Scale-Out
  • WebApi Integration
  • Security