Real Time Data in Web Applications
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
HTTP: Synchronous, Delayed, Server Load
D el ay Client Server HTTP Request HTTP Response HTTP Request HTTP Response"Real Time" Data Source
Notification Notification B lo ck B lo ck P o lli n g In te rv al
AJAX: Delay, Server Load
D el ay Client Server HTTP Request (synchronous) HTTP ResponseAJAX Request (async)
"Real Time" Data Source
Notification Notification (B lo ck ) AJAX Response P o lli n g In te rv al
AJAX Request (async) AJAX Response
WebSockets: Server-Push, “Real Time”
(D el ay ) Client Server WS: Connect (HTTP) WS: Connected"Real Time" Data Source
Notification Notification (B lo ck ) WS: Event Notification WS: Event WS: Event
Getting Started with
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.
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.
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‘ ] });
Parts on SignalR Server and JavaScript Client
Hub
IAppBuilder.MapSignalR() // "/signalR/hubs"
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(…);
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 */ });
// any .NET application
Parts on a .NET Client
(same on the Server)
// conceptually the same as in JavaScript
----// configure, if asp.net signalR app; get (generic) proxy.
var hubConnection = new HubConnection("http://<host>/signalr");
IHubProxymyHubProxy = 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>);
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
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>); |
Unit Testing
SignalR Hub under Test: Callback invocation?
Clients.Others.broadcastMessage( string resourceKey,
ResourceStatus status
?
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
Real Life / Scale Out
Live Demo II: Resource Status Notification
ASP.NET SignalR App
Data Source
HTML/JavaScript Client
Hub Proxy SignalR
Hub
Subscribe to Resource Status
Notify Satus Changes
REST Client (AJAX) Invoke Resources Observer Request Resource REST Client (.NET) WEB API Controller PUT/POST Resource Data Sink CRUD Resource Resource Manager (Cache, DB,...) Notify Observe Notify
Scale Out
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 )
Q&A
Read more at http://www.asp.net/signalr
Martin Schreiber