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

Post on 13-Jul-2020

10 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

© 2010 RoCk SOLiD KnOwledge Ltd.

SignalR

Kevin Jones

kevin@rocksolidknowledge.com

@kevinrjones

http://www.github.com/kevinrjones

© 2010 RoCk SOLiD KnOwledge Ltd.2

Why Async?

Why SignalR?

SignalR low level

Hubs

Dependency Injection

Deferred work

Agenda

© 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

© 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

© 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'

});

© 2010 RoCk SOLiD KnOwledge Ltd.6

Using the browser

Better techniques

Long polling

Forever frame

Server Sent Events

Web Sockets

© 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

© 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

© 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

© 2010 RoCk SOLiD KnOwledge Ltd.10

Web Sockets

Implemented in modern browsers

2-way communication over sockets

Needs server support

Coming in Windows 8

© 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

© 2010 RoCk SOLiD KnOwledge Ltd.12

SignalR usage

Can work at a low level

Can use the hubs feature

© 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();}

}}

© 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){...}

}

© 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);

}}

© 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

© 2010 RoCk SOLiD KnOwledge Ltd.17

Defining a Hub

Derive from Hub base class

public class TheatreBookingHub : Hub{

© 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){}

}

© 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);

}}

© 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

© 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));

}}

});

© 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();

});});

© 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);});

© 2010 RoCk SOLiD KnOwledge Ltd.24

Creation semantics

Hub is created for each call

Don't maintain state in the hub

© 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();}

}

© 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);}

}

© 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());

}}

© 2010 RoCk SOLiD KnOwledge Ltd.28

Register a Client Callback

Before the hub starts

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

};

© 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;

});}

© 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; }

}

© 2010 RoCk SOLiD KnOwledge Ltd.31

Client Side Configuration

Can configure the client

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

© 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);

});

© 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)

});

© 2010 RoCk SOLiD KnOwledge Ltd.

Q & A

kevin@rocksolidknowledge.com

http://rocksolidknowledge.com/blogs

top related