Upgrade to Pro — share decks privately, control downloads, hide ads and more …

"I wanna be cool!" - Push communication with Si...

"I wanna be cool!" - Push communication with SignalR for the web & beyond

Google, Facebook & Co. are leading the way: users want to see data and updates, live & now. There is need for a server or service to send messages and data into clients – without the client actually explicitly asking. Christian Weyer shows how .NET developers can implement this with SignalR – a framework with a simple yet powerful programming model. You should not have to care about the underlying protocols and (quasi-) standards in order to realize bi-directional communication over standard network infrastructure with potentially any device (desktop, browser, mobile) – not just for the web.

Christian Weyer

March 06, 2013
Tweet

More Decks by Christian Weyer

Other Decks in Programming

Transcript

  1. DevWeek 2013 I wanna be cool! Push communication with SignalR

    for the web & beyond Christian Weyer [email protected] think mobile!
  2. 2 Christian Weyer • Solution architect and principal consultant at

    thinktecture • Focus on – distributed applications, service orientation – cloud computing – interoperability, cross device – pragmatic end-to-end solutions – Windows Server, ASP.NET, Web API, SignalR, WCF, Windows Azure • Microsoft MVP for Windows Azure (Architecture) • ASP.NET Web API Advisory Board Member • SignalR Course Author • http://blogs.thinktecture.com/cweyer • [email protected] • @christianweyer think mobile!
  3. 4 Real time: Problem space  It is all about

    the users  Users want data  Now & instant  Up-to-date  Delivered to any device, over any connection  Increasing number of web sites & web applications offer ‚real time‘ data  Live searches/updates  Stock streamers, auctions  Live scores, betting, interactive games  Collaborative apps  In general: Real-time feedback, real-time notifications
  4. 5 Real time: Developers’ world  Developers look for ways

    to provide real time data  But not only for web applications  What about mobile devices & apps?  What about traditional desktop applications?  What about server-to-server?  Web-based push communication beyond the web is a need  We got accustomed to a service-oriented design  Think in service facades  Facades provide entry points into our logic & data access  Think, design & implement Push Services
  5. 6 Push Services pattern  ‘Push Services’ are really not

    an official pattern  Model a service that  accepts incoming connections from callers  is able to push data down to callers  abstracts from communication nitty-gritty details  Realize Publish-Subscribe semantics  Based on standard web technologies with reach in mind  With maximum reach into any device, platform Push Service Consumer Send data External event (Database) External event (Message queue) External event (Other actor) Notify [data]
  6. 7 HTTP is the protocol  When talking about web

    communication technologies we talk about HTTP  HTTP is warrantor for ubiquity & reach  HTTP is inherently request-response, n’est pas?  Still we need to realize Push Services with what HTTP gives us
  7. 9 Long polling Poll but don’t respond untill there’s data

     Server holds on to the HTTP request until there is data to return  (Re-)Poll after data received or after the connection times out  Consumes server threads & connection resources Server Client
  8. 10 Technical approaches for push  Periodic Polling  Long

    Polling  HTTP Streaming / Comet  Forever Frame  Server-Sent Events (SSE)  Web Sockets  Easy: Web Sockets are the way to go!  Only with Windows 8/Server 2012  Network considerations  Maybe some time, but not today  Alright, let’s just write code for any technology & technique!  Erm… really? For any server and any client platform?
  9. 12 ASP.NET SignalR as a solution  SignalR is 

    a server-side framework to write push services  a set of client libraries to make push service communication easy to use on any platform  optimized for asynchronous processing  Abstracts from the different techniques to implement pushing data  Mental model is a persistent connection  Volatile, non-durable  ‘Signal’, anyone?  Sending data to a signal. E.g. represented by a connection ID  Part of the ASP.NET brand, but not tied into ASP.NET runtime and APIs
  10. 13 ASP.NET SignalR development  Extensible framework & pipeline 

    Based on interfaces & DI  Two programming models  Persistent connections  Hubs  Hubs offer a pre-defined application-level protocol in an RPC- ish style  Easy-to-get-going means for 80/20 situations
  11. 14 Hubs concept  Hubs are classes to implement push

    services in SignalR  Abstraction on top of persistent connection  Convention-over-configuration  Hubs provide a higher level RPC framework  Perfect for different types of messages to send between server and client  Hub conventions  Public methods are callable from the outside  Send messages to clients by invoking client-side methods  Simple steps to get going 1. Write hub class 2. Add route in host process 3. Done
  12. 15 Programming model  Hub name reflected into external API

     [HubName] can alias name  Return simple type, complex type or Task  Complex objects and arrays of objects automatically serialized/deserialized to/from JSON  Default is JSON.NET  Context holds connection- and request-specific information  ConnectionId  Request  Headers  RequestCookies  QueryString  User
  13. 16 Hubs protocol  Base endpoint is /signalr  Optional:

    get JS metadata from /signalr/hubs  Basically two protocol steps (details vary by transport)  /negotiate: which transport do you support?  (optional: /ping server)  /connect: OK, here is my persistent connection  ‘Best’ transport negotiation  Web Sockets  SSE  Forever frame  Long polling  Pre-defined payload  Any data is JSON encoded C: Cursor M: Messages H: Hub name M: Method name A: Method args T: Timeout D: Disconnect
  14. 17 Pushing data: Clients  Clients property as dispatching point

    to send messages to clients  Holds dynamic properties and methods  Target method with parameters is dynamically ‘injected’ into code path, serialized, and embedded into protocol response public void SendMessage(string message) { var msg = string.Format("{0}: {1}", Context.ConnectionId, message); Clients.All.newMessage(msg); }
  15. 18 Pushing data: Groups  Groups  Typical base pattern

    in push scenarios  Can add connections to groups and send messages to particular groups  Groups are not persisted on the server  We need to keep track of what connections are in what groups  No automatic group count public void JoinRoom(string room) { Groups.Add(Context.ConnectionId, room); } public void SendMessageForRoom(string room, string message) { var msg = string.Format("{0}: {1}", Context.ConnectionId, message); Clients.Group(room).newMessage(msg); }
  16. 19 Hub lifecycle  Hub connections have a lifecycle 

    Override async pipeline event handlers  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); } public override Task OnConnected() { … } public override Task OnDisconnected() { … } public override Task OnReconnected() { … }
  17. 20 Hub consumers  Consumers can be classic client applications

    or other services/hubs  SignalR provides a variety of client libraries  Microsoft SignalR team  .NET 4.0+  WinRT  Windows Phone 8  Silverlight 5  jQuery  C++  Community  iOS native  iOS via Mono  Android via Mono
  18. 21 jQuery client  HTML5-based applications often use jQuery 

    JSON-based wire protocol makes it easy to integrate with JavaScript  SignalR jQuery plugin offers two approaches  Proxy-based with generated proxy  Without proxy but ‘late binding’ Install-Package Microsoft.AspNet.SignalR.JS
  19. 22 jQuery with proxy  Automatic proxy code via /signalr/hubs

     Script generated based on hubs declaration in .NET  ‘Contract’ if you will  Optionally: create static proxy file via signalr.exe tool  Simple steps to get going 1. Get reference to hub 2. Wire up events 3. Start hub connection 4. Call method 5. Done  Hubs become properties on $.connection  E.g. $.connection.chatHub  Hub name camel cased
  20. 23 jQuery with proxy - II  $.connection.hub.start can take

    transport configuration  Auto, or any of the supported persistent connection transports  [hub].server.abc  Call methods on the server hub  [hub].client.xyz  Define client-side methods to be invoked by server hub var chat; chat = $.connection.chat; chat.client.newMessage = onNewMessage; var chat; chat = $.connection.chat; $.connection.hub.start({ transport: 'longPolling'}); chat.server.joinRoom('private');
  21. 24 jQuery with proxy - III  Round-tripping data/state via

    state property  error handler with error string on $.connection.hub  Events for connection state handling  Detect slow connections  Based on ‘keep alive’  $.connection.hub.connectionSlow  Client-side logging into JavaScript console  Cross-domain support  Web Sockets, CORS-enabled long polling, or JSONP long polling  Cross-domain URLs are auto detected  Enforce JSONP via start config option
  22. 25 jQuery without proxy file  We can also use

    a late binding approach  Simple steps to get going 1. Create hubConnection  Derived from $.connection 2. Get dynamic proxy 3. Wire up events based on method/event handler name via on 4. Start & invoke methods based on method name via invoke  Same connection-related event handlers  Cross-domain support same as with static proxy var connection = $.hubConnection(); var proxy = connection.createHubProxy('chat'); proxy.on('newMessage', onNewMessage); connection.start(); proxy.invoke('sendMessage', $('#message').val());
  23. 26 .NET client  Client NuGet package contains binaries for

    all supported .NET flavors  .NET 4.x, SL5  WP8, WinRT  Mental model resembles proxy-less JavaScript approach  Simple steps to get going 1. Create HubConnection 2. Create hub proxy via CreateHubProxy 3. Wire up event handlers via On 4. Start connection with Start 5. Call methods via Invoke Install-Package Microsoft.AspNet.SignalR.Client var hubConnection = new HubConnection("http://localhost/services"); var chat = hubConnection.CreateHubProxy("chat"); chat.On<string>("newMessage", …); hubConnection.Start().Wait(); …
  24. 27 ASP.NET hosting  SignalR ASP.NET hosting sits on top

    of OWIN  Create routes for hubs  Referenced assemblies are scanned for Hub implementations public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { // Register the default hubs route: ~/signalr RouteTable.Routes.MapHubs(); } } Install-Package Microsoft.AspNet.SignalR
  25. 28 Self hosting  Self hosting sits on top of

    OWIN  IAppBuilder API  Simple steps to get going 1. Define startup class with IAppBuilder method signature 2. Map hubs onto IAppBuilder (route) 3. No automatic scanning of referenced assemblies  Startup class used in WebApplication.Start to spin up server  HTTP or HTTPS base URL  jQuery client needs to explicilty set connection URL Install-Package Microsoft.Owin.Hosting -pre Install-Package Microsoft.Owin.Host.HttpListener -pre Install-Package Microsoft.AspNet.SignalR.Owin
  26. 29 Windows Azure  Cloud Services  ASP.NET hosting in

    Web Role  Self hosting in Worker Role  Windows Azure Web Sites  ASP.NET hosting  IaaS/VMs  Do what you want  But: watch out for scale-out issues  Which server instance handles the client request?  Which instance pushes?  Scale-out providers for multi-node environments
  27. 30 Summary  Real-Time Web Communication  Push Services pattern

     ASP.NET SignalR  Hubs  jQuery Clients  .NET Clients  Hosting