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

Daten - jetzt! Leichtgewichtige Push-Kommunikation mit ASP.NET SignalR

Daten - jetzt! Leichtgewichtige Push-Kommunikation mit ASP.NET SignalR

Ja, es ist cool – aber da ist mehr: Zeitnahes Bereitstellen von aktuellen Daten ist ein wichtiger Erfolgsfaktor in modernen Anwendungen. Benutzer wollen in "Near-Real-Time"-Manier mit Datenupdates in Client-Apps jeglicher Ausprägung versorgt werden. Christian Weyer zeigt anhand des ASP.NET-SignalR-Frameworks, wie man Push Services implementiert und Clients für .NET, Windows 8, iOS, Android und selbstvertständlich für den Browser auf Basis anerkannter Webstandards wie HTTP oder WebSockets anbindet. Es ergeben sich so zahlreiche Möglichkeiten, Ihre Software für den Benutzer "zu verbessern" und für den Entwickler "zu vereinfachen". Push Baby!

Christian Weyer

September 24, 2013
Tweet

More Decks by Christian Weyer

Other Decks in Programming

Transcript

  1. 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 / ASPInsider • http://blogs.thinktecture.com/cweyer • [email protected] • @christianweyer think mobile!
  2. 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
  3. 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
  4. Push Services pattern  ‘Push Services’ are really not an

    official pattern  Observer pattern, anyone?  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]
  5. 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
  6. 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
  7. 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?
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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); }
  14. 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); }4
  15. 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() { … }
  16. 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
  17. 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’
  18. 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
  19. 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');
  20. 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());
  21. .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 var hubConnection = new HubConnection("http://localhost/services"); var chat = hubConnection.CreateHubProxy("chat"); chat.On<string>("newMessage", …); hubConnection.Start().Wait(); …
  22. ASP.NET hosting  SignalR ASP.NET hosting integrates with RouteTable 

    Create routes for hubs  Referenced assemblies are scanned for Hub implementations  In v2 hosting sits on top of OWIN public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { // Register the default hubs route: ~/signalr RouteTable.Routes.MapHubs(); } }
  23. 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
  24. SignalR & Web API  Web API == “incoming API”

     SignalR == “outgoing API”  Can easily leverage same pipeline extensions public abstract class HubApiController<THub> : ApiController where THub : IHub { private Lazy<IHubContext> hub = new Lazy<IHubContext>( () => GlobalHost.ConnectionManager.GetHubContext<THub>()); protected string ConnectionId { get { var connectionId = new FormDataCollection(Request.RequestUri). Get("connectionId"); return connectionId; } } protected IHubContext Hub { get { return hub.Value; } } }
  25. Summary  Deliver data to your users & consumers –

    everywhere  Building push services with an easy-to-use programming model  SignalR hubs  Consume push services on nearly any platform  Various clients libs for a plethora of programming languages  SignalR can be hosted side-by-side or be combined with Web APIs  Watch-out for scaling out SignalR server side
  26. Resources • [email protected] • http://www.thinktecture.com • thinktecture’s GitHub Repositories –

    https://github.com/thinktecture • Christian Weyer’s GitHub Repositories – https://github.com/ChristianWeyer • ASP.NET SignalR – http://www.asp.net/signalr 30