>sddconf.com/brands/sdd/library/signalr.pdfinstall-package microsoft.aspnet.signalr add a startup...

34
© 2010 RoCk SOLiD KnOwledge Ltd. SignalR Kevin Jones [email protected] @kevinrjones http://www.github.com/kevinrjones

Upload: others

Post on 13-Jul-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.

SignalR

Kevin Jones

[email protected]

@kevinrjones

http://www.github.com/kevinrjones

Page 2: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.2

Why Async?

Why SignalR?

SignalR low level

Hubs

Dependency Injection

Deferred work

Agenda

Page 3: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.3

Asynchronous applications i

Building event driven asynchronous applications is 'easy'

User clicks on button

Event fires

Use Ajax to call back to server

Update UI if/when server returns

Page 4: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.4

Asynchronous applications ii

However that covers only one scenario

What about server push?

What about client to client communication

Client could poll

This has issues

What if no data is available?

How long should the poll interval be

Connection has to be managed

Page 5: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.5

Async code in the browser

Can use the Xml Http Request object (xhr)

Typically wrap in jQuery

$.ajax({type: 'post',url: '/Todo/Update',data: getData(options),success: function () {

alert('done');},contentType: 'application/json'

});

Page 6: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.6

Using the browser

Better techniques

Long polling

Forever frame

Server Sent Events

Web Sockets

Page 7: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.7

Long Polling

Open a connection to the server

Keep the connection open waiting for data

Wait for server to send data

Connection will eventually timeout

Re-open connection

Page 8: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.8

Forever Frame

Create an iFrame

Frame opens connection to server

Send data to the frame

Uses chunked encoding so data size does not need to be known

Page 9: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.9

Server Sent Events

New standard

Like web sockets but one way only

Server -> Client

Appear as JavaScript events in the browser

Page 10: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.10

Web Sockets

Implemented in modern browsers

2-way communication over sockets

Needs server support

Coming in Windows 8

Page 11: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.11

Enter SignalR

Made for ASP.Net

Server and client side libraries

Open source

Available on GitHub and Nuget

Wraps all the previous issues

Page 12: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.12

SignalR usage

Can work at a low level

Can use the hubs feature

Page 13: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.13

Installing

Install via NuGet

Install-package Microsoft.AspNet.SignalR

Add a startup class

[assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]namespace TheatreBookingWeb{

public class Startup{

public void Configuration(IAppBuilder app){

app.MapSignalR();}

}}

Page 14: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.14

Low level API - PersistentConnection

PersistentConnection

Various methods that are called asynchronously

public class SimpleConnection : PersistentConnection{protected override Task OnConnectedAsync(IRequest request,

string connectionId){...}protected override Task OnDisconnectAsync(string connectionId) {...}protected override Task OnErrorAsync(Exception error) {...}protected override Task OnReconnectedAsync(IRequest request,

IEnumerable<string> groups, string connectionId) {...}

protected override Task OnReceivedAsync(IRequest request, string connectionId, string data){...}

}

Page 15: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.15

Low level API - PersistentConnection

Derive class from PersistentConnection

Called asynchronously

Connection.Broadcast to all listeners

Conection.Send to specific listener

public class SimpleConnection : PersistentConnection{

protected override Task OnReceivedAsync(IRequest request, string connectionId, string data)

{return Connection.Broadcast(data);

}}

Page 16: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.16

Hub model

Nobody uses PersistentConnections

Use 'Hubs' instead

Hubs provide an easier model than PersistentConnections

No routing to set up

Provides a generated proxy

Page 17: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.17

Defining a Hub

Derive from Hub base class

public class TheatreBookingHub : Hub{

Page 18: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.18

Hub methods

Can define methods on the hub

public class TheatreBookingHub : Hub{

public void BookSeat(string row, int seatNumber, bool booked){}

}

Page 19: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.19

Hub members

Caller and Clients

Caller is the current executing browser

Clients are all the connected clients

public class TheatreBookingHub : Hub{

public void GetInitialData(){

Caller.initializeTheatre(Theatre);}

public void BookSeat(string row, int seatNumber, bool booked){

Theatre.UpdateSeat(row, seatNumber, booked);Clients.updateTheatre(Theatre);

}}

Page 20: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.20

Generates JavaScript

Proxy generated from the C#

Referenced from the browser

<script type="text/javascript" src="/signalr/hubs"></script>

'virtual' URL

Can be changed by adding a route

Page 21: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.21

Generated JavaScript

/// <reference path="jquery-1.6.2.js" />(function ($, window) {

/// <param name="$" type="jQuery" />"use strict";

// ...// Create hub signalR instance$.extend(signalR, {

theatreBookingHub: {_: {

hubName: 'TheatreBookingHub',ignoreMembers: ['bookSeat', 'getInitialData', 'namespace',

'ignoreMembers', 'callbacks'],connection: function () { return signalR.hub; }

},

bookSeat: function (booked, row, seatNumber, callback) {return serverCall(this, "BookSeat", $.makeArray(arguments));

}}

});

Page 22: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.22

Provide corresponding code in client

Client can call methods on the hub

Hub can call methods on the client

$(function () {theatre = $.connection.theatreBookingHub;

theatre.server.updateTheatre = function (data) {updateModel(data);

};

theatre.client.initializeTheatre = function(data) {viewModel = new TheatreViewModel(data, theatre);updateUI(viewModel);

};

$.connection.hub.start(function () {theatre.getInitialData();

});});

Page 23: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.23

Hub return types

Anything returned from Hub method is serialized to the caller

Caller returns a jQuery deferred

theatre.getInitialData().done(function (theatreData) {

theatre.initializeTheatre(theatreData);});

Page 24: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.24

Creation semantics

Hub is created for each call

Don't maintain state in the hub

Page 25: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.25

Sending from outside a Hub

May want to call clients when not in a hub

public class Notifier{

public void Notify(string message){

var context = GlobalHost.ConnectionManager.GetHubContext<TheatreHub>();

context.Clients.All.Tick();}

}

Page 26: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.26

Using IRegisteredObject

public class BackgroundUptimeServerTimer : IRegisteredObject{

private readonly IHubContext _uptimeHub;private Timer _timer;

public BackgroundUptimeServerTimer() {_uptimeHub = GlobalHost.ConnectionManager.GetHubContext<MyHub>();StartTimer();

}private void StartTimer() {

_timer = new Timer(BroadcastUptimeToClients, null, 2000, 1000);}private void BroadcastUptimeToClients(object state) {

_uptimeHub.Clients.All.Tick();}

public void Stop(bool immediate) {_timer.Dispose();

HostingEnvironment.UnregisterObject(this);}

}

Page 27: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.27

Register It

public class WebApiApplication : System.Web.HttpApplication{

protected void Application_Start(){

GlobalConfiguration.Configure(WebApiConfig.Register);FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);RouteConfig.RegisterRoutes(RouteTable.Routes);BundleConfig.RegisterBundles(BundleTable.Bundles);HostingEnvironment.RegisterObject(new BackgroundUptimeServerTimer());

}}

Page 28: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.28

Register a Client Callback

Before the hub starts

$.connection.kelloHub.client.tick = function() {console.log("tick");

};

Page 29: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.29

Can also return Task<T>

Can do async work

public Task<Theatre> GetInitialData(){

return Task.Factory.StartNew(() =>{

// Don't do this in the real worldThread.Sleep(500);return Theatre;

});}

Page 30: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.30

Other HTTP data

Context data member of type HubCallerContext

public class HubCallerContext{

public string ConnectionId { get; private set; }public IRequestCookieCollection RequestCookies { get; private set; }public NameValueCollection Headers { get; private set; }public NameValueCollection ServerVariables { get; private set; }public NameValueCollection QueryString { get; private set; }public IPrincipal User { get; private set; }

}

Page 31: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.31

Client Side Configuration

Can configure the client

$.connection.hub.start( { transport: ['webSockets', 'longPolling'] });

Page 32: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.32

Connection Lifetime Events

The client fires events at start, stop etcstarting

received

connectionSlow

reconnecting

reconnected

stateChanged

disconnected

$.connection.hub.stateChanged(function(oldState, newState) {console.log(oldState, newState);

});

Page 33: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.33

Handling Errors

Can log errors on the client

// on the servervar hubConfiguration = new HubConfiguration(); hubConfiguration.EnableDetailedErrors = true; app.MapSignalR(hubConfiguration);

$.connection.hub.error(function (error) { console.log('SignalR error: ' + error)

});

Page 34: >sddconf.com/brands/sdd/library/signalr.pdfInstall-package Microsoft.AspNet.SignalR Add a startup class [assembly: OwinStartup(typeof(TheatreBookingWeb.Startup))]

© 2010 RoCk SOLiD KnOwledge Ltd.

Q & A

[email protected]

http://rocksolidknowledge.com/blogs