Martin Schreiber push push push
Agenda 1. Real Time Data and HTTP? HTTP AJAX WebSockets 2. Getting Started with ASP.NET SignalR 2.x RPC Connection Transport Behavior Server JavaScript Client.NET Client Security DI 3. Unit Testing of SignalR Hubs Callback Invocation Mocking 4. Real Life / Scale Out of SignalR Apps Live Demo Backplane 5. Q & A 2 5/21/2015
Real Time Data and HTTP? 3 5/21/2015
HTTP: Synchronous, Delayed, Server Load Client Server "Real Time" Data Source Polling Interval Block HTTP Request HTTP Response Notification HTTP Request Delay HTTP Response Block Notification 4 5/21/2015
AJAX: Delay, Server Load Client Server "Real Time" Data Source Polling Interval (Block) HTTP Request (synchronous) HTTP Response AJAX Request (async) Delay Notification AJAX Response Notification AJAX Request (async) AJAX Response Notification 5 5/21/2015
WebSockets: Server-Push, Real Time Client Server "Real Time" Data Source (Block) WS: Connect (HTTP) WS: Connected WS: Event WS: Event (Delay) Notification Notification WS: Event Notification 6 5/21/2015
Getting Started with ASP.NET SignalR 2.x 7 5/21/2015
SignalR: Framework for remote procedure calls (RPC) Server-to-client: call JavaScript in client browsers from server-side.net code. Client-to-server: call server-side.net code from JavaScript in client browsers. 8 5/21/2015
SignalR Connection Persistent unlike the classic HTTP (reestablished per request) Connection management supports reconnect on connection loss Broadcast server-push rather than request-response Server to specific client Server to all clients (thousands; see scale-out) Server to groups of clients 2 Levels of abstraction PersistentConnection class hides connection/transport details; message-based. Hub class hides client addressing details (groups etc.); operation-based. 9 5/21/2015
SignalR Transport WebSockets (based on TCP) Client: http://caniuse.com/#feat=websockets ( ) Server:.NET 4.5, IIS 8 (Windows Server 2012 Windows 8), Windows Azure Automatic Fallback on connection while connection HTTP WebSockets (server memory efficiency, lowest latency, duplex communication) Server Sent Events (HTML5; except IE) Forever Frame (only IE; 1 connection for request; 1 for responding scripts) Ajax long polling ( server delays response until data is available; or timeout occurs. Client reconnects.) Manual selection @ connection open connection.start({ transport: [ 'websockets', 'serversentevents', 'foreverframe', 'longpolling ] }); 10 5/21/2015
Parts on SignalR Server and JavaScript Client IAppBuilder.MapSignalR() // "/signalr/hubs" Hub public class MyHub : Hub { public void /*Task*/ MyMethod(<client data>) { // Clients.All.myMethod(<push data>); Clients.AllExcept(<connectionId>, ).mymethod( ); Clients.Caller.myMethod( ); Clients.Client(<connectionId>).myMethod( ); Clients.Clients(<connectionId>, ).mymethod( ); Clients.Group(<group name>).mymethod( ); Clients.Groups(<group name>, ).mymethod( ); Clients.Others.myMethod( ); Clients.OthersInGroup(<group name>).mymethod( ); Clients.OthersInGroups(<group name>, ).mymethod( ); Clients.User(<user id>).mymethod( ); Clients.Users(<user id>, ).mymethod( ); 11 5/21/2015
Parts on SignalR Server and JavaScript Client <script src=" /jquery-2.1.1.min.js"/> <script src=" /jquery.signalr-2.x.min.js"/> <script src="/signalr/hubs"/> <!-- if outside asp.net app --> <script src="http://<host>/signalr/hubs"/> // configure, if asp.net signalr app: $.connection.hub.url = "http://<host>/signalr"; var myhubproxy = $.connection.myhub; // register call-backs myhubproxy.client.mymethod = function (<server push data>) { /* call-back */ }; // connect $.connection.hub.start().done( function () { /* wire up */ }).fail( function () { /* handle err */ }); // invoke hub method myhubproxy.server.mymethod(<client data>).done( function () { /*... */ }).fail( function () { /* handle err */ }); // 12 5/21/2015
Parts on a.net Client (same on the Server) // any.net application // ---- conceptually the same as in JavaScript ---- // configure, if asp.net signalr app; get (generic) proxy. var hubconnection = new HubConnection("http://<host>/signalr"); IHubProxy myhubproxy = hubconnection.createhubproxy("myhub"); // register call-backs myhubproxy.on<<server push data>>( "MyMethod", <server push data> => /* handle call-back */ ); // connect await hubconnection.start(); // invoke hub method myproxy.invoke("mymethod", <client data>); // 13 5/21/2015
SignalR Security SignalR uses Authentication of the hosting App Hubs [Authorize( )] on hub class, and/or hub method. [Authorize(RequireOutgoing = false)] outgoing calls w/o authorization. GlobalHost.HubPipeline.RequireAuthentication(); enforce global auth. Override AuthorizeAttribute.UserAuthorized( ) for custom authorization. PersistentConnection Override <Connection>.AuthorizeRequest(IRequest request). 14 5/21/2015
SignalR Dependency Injection SignalR creates hubs for you > no control over instantiation Register function for Constructor Injection : GlobalHost.DependencyResolver.Register( typeof(myhub1), () => new MyHub1(<dependency>)); IoC Containers Unity.WebApi container.registerinstance<<dependency interface>>(new <dependency()>); GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(<container>); Unity.Mvc5, Ninject, Castle Windsor, Spring.Net, Autofac, StructureMap 15 5/21/2015
Unit Testing of SignalR Hubs 16 5/21/2015
SignalR Hub under Test: Callback invocation? IHubCallerContext<dynamic> Clients.Others.broadcastMessage( string resourcekey, ResourceStatus status );? 17 5/21/2015
Live Demo I: Add Hub to Project; Test-Driven Adding a Hub to ASP.NET SignalR Project, Unit-Test Client Contract Preparation: ASP.NET Web Application Msugs2015.RealTimeWeb.SignalRApp Empty, [x] Add Unit tests PM> install-package Microsoft.AspNet.SignalR (2x) PM> install-package Moq (in test project) Demo: Add new Hub, define Client and Server Contracts Setup Unit Test. Verify Callbacks to Clients are invoked. 18 5/21/2015
Real Life / Scale Out of SignalR Apps 19 5/21/2015
Live Demo II: Resource Status Notification ASP.NET SignalR App Observe Notify Resources Observer Notify SignalR Hub WEB API Controller Subscribe to Resource Status Notify Satus Changes Request Resource HTML/JavaScript Client Hub Proxy Invoke REST Client (AJAX) Data Sink Resource Manager (Cache, DB,...) CRUD Resource PUT/POST Resource Data Source REST Client (.NET) 20 5/21/2015
Scale Out? 21 5/21/2015
Scale Out: Backplane Backplane SignalR App sends Message to Backplane Backplane sends Msg to each SignalR App IMessageBus (pub/sub abstraction) Backplane Services Azure Service Bus ( Azure messaging infrastructure; $ ) Redis http://redis.io/ ( In-Memory key-value store, supports Pub/Sub, Replication etc. ) SQL Server Message Broker ( Messages in Tables ) 22 5/21/2015
Q&A Read more at http://www.asp.net/signalr Martin Schreiber martin.schreiber@trivadis.com 23 5/21/2015