什么是SignalR?
ASP.NET SignalR 是一個讓 ASP.NET開發者可以簡單地給自己的程序添加即時通訊功能的開發庫。即時通訊功能可以直接從服務器端給在線的客戶端發送數據,而不用等待客戶端請求數據再返回數據。
SignalR提供了一個簡單的api來創建服務器--客戶端的遠程工程調用協議(RPC),可以通過服務器端的C#代碼調用瀏覽器端的javascript函數(或者其他的平台)。SignalR也提供了連接管理,和Group連接管理的api。
SignalR和WebSocket
如果客戶端和服務器都支持WebSocket,那么SignalR會通過WebSocket來傳輸數據。當然你也可以自己使用WebSocket來實現SignalR的功能,不過使用SignalR你就不用考慮如果客戶端或者服務器不支持WebSocket的問題了。
SignalR的協議選擇
SignalR是可以在客戶端和服務器端進行即時通訊的幾種協議的抽象和實現。一個SignalR連接是通過http請求發起的,然后上升為WebSocket(如果客戶端和服務端都支持)。WebSocket是SignalR最理想的協議,它可以有效地利用服務器端的內存,有着最低的延遲,最多的基礎特性(比如客戶端和服務端的全雙工連接),不過它也有着嚴格的要求,需要服務器端使用Windows Server 2012或者Windows 8以上的系統,也需要.NET Framework 4.5.。如果不符合這些要求,那么SignalR會使用其他的協議來建立連接。
HTML 5協議
下面的兩種協議基於HTML5,如果客戶端不支持HTML5,那么會使用其他的協議進行通訊。
- WebSocket。如果服務器和客戶端都支持,那么就使用WebSocket協議來進行通訊。
- 服務器推送事件(Server-sent Events)。除了IE,其他的瀏覽器基本都支持。
Comet協議
下面兩種協議都是基於Comet模型。
- Forever Frame (只支持IE)。
- Ajax長輪詢(Ajax long polling)。
SignalR協議選擇過程
下面的列表顯示SignalR是如何選擇具體使用的協議。
- 如果瀏覽器是IE8或者更早的版本,使用長輪詢。
- 如果配置了Jsonp(如果連接開始的時候jsonp的參數設置為true), 使用長輪詢。
- 如果是跨域連接, 如果下面的條件符合就會使用WebSocket,如果有條件不符合,那就是用長輪詢。
- 客戶端支持跨域連接
- 客戶端支持WebSocket
- 服務器端支持WebSocket
- 如果沒有配置jsonp,而且不是跨域連接,如果客戶端和服務端都支持WebSocket,那么就使用WebSocket。
- 如果客戶端或者服務端不支持WebSocket,使用服務器推送事件。
- 如果不支持服務器推送事件,使用Forever Frame。
- 如果不支持Forever Frame,使用長輪詢。
監控協議
你可以通過在你的Hub上開啟logging來監控你的SignalR使用了什么協議。
你需要在你的客戶端代碼里加入以下代碼
$.connection.hub.logging = true;
指定協議
SignalR判斷協議也需要消耗一定的客戶端、服務端資源,如果你清楚客戶端、服務端支持的協議,那么你可以指定使用某種協議來建立連接。
比如,你知道客戶端只支持長輪詢,那么你可以指定使用長輪詢來進行通訊。
connection.start({ transport: 'longPolling' });
你也可以指定一個序列,客戶端會按照序列里的順序來進行通訊。下面的代碼的作用是,先使用WebSocket,如果失敗了,就使用長輪詢。
connection.start({ transport: ['webSockets','longPolling'] });
SignalR包含下面四種指定的協議常量:
- webSockets
- foreverFrame
- serverSentEvents
- longPolling
連接和Hubs
SignalR api為了客戶端和服務端通訊,建立了兩個模型:持久連接和Hubs。
一個持久連接代表了一個端點,它可以發送單一接收者,Group接受者或者廣播信息。持久連接的api是SignalR提供給開發者進入低級別協議的api。連接模型使用起來和WCF比較類似。
Hubs是SignalR提供的高級別的api,它允許客戶端和服務端,在自己這邊相互調用對方的方法。Hubs模型類似於.Net Remoting。使用Hubs也可以讓你傳遞強類型參數,進行模型綁定。
SignalR架構圖
下面的結構圖顯示了Hubs,持久連接,和SignalR所使用的底層協議之間的聯系。
Hubs如何工作
當服務端代碼調用客戶端的方法,一個信息包會通過當前使用的協議傳輸出去,里面包含了所調用方法的名字和參數(如果參數是一個對象,那么會使用json序列化)。客戶端會去匹配方法名,如果客戶端有服務端調用的方法,那么客戶端會代入參數數據並執行方法。
方法的調用可以使用Fiddler或者其他工具來進行追蹤。
下面圖片顯示的就是Fiddler抓取到的一次SignalR調用記錄。方法是通過一個叫MoveShapeHub的Hub來調用的,執行的客戶端方法名是updateShape。
這個例子里H參數是Hub名字,參數名是M參數,而方法的參數數據是A參數。
如何挑選通訊模型
大部分情況下會使用Hub api來進行通訊。下面幾種情況則使用連接api。
- 強制指定發送信息的模型。
- 開發者比起遠程調度模型,更喜歡使用消息傳遞和調度模型。
- 原來的應用使用了消息調度,現在接口需要使用SignalR。
服務端要求
操作系統
SignalR組件可以在Win7、Windows Server 2008 R2及更高級別系統上運行。如果需要支持WebSocket,那么需要使用Win8和Windows Server 2012及更高級別的系統。
IIS版本
- IIS 8 or IIS 8 Express及更高級版本。
- IIS 7 and 7.5。需要支持extensionless URLs。
- IIS必須在集成模式下進行,不支持經典模型。如果在經典模式下使用Server-Sent Events協議,那么延遲可能超過30秒。
- 宿主程序必須在完全信任的級別下運行。
客戶端要求
瀏覽器
協議 | Internet Explorer | Chrome (Windows or iOS) | Firefox | Safari (OSX or iOS) | Android |
---|---|---|---|---|---|
WebSockets | 10+ | current - 1 | current - 1 | current - 1 | N/A |
Server-Sent Events | N/A | current - 1 | current - 1 | current - 1 | N/A |
ForeverFrame | 8+ | N/A | N/A | N/A | 4.1 |
Long Polling | 8+ | current - 1 | current - 1 | current - 1 | 4.1 |
Windows桌面和Silverlight
協議 | .NET application | Silverlight |
---|---|---|
Web Sockets | Windows 8+ and .NET 4.5+ | N/A |
Forever Frame | N/A | N/A |
Server-Sent Events | .NET 4+ | 5+ |
Long Polling | .NET 4+ | 5+ |
Windows Store and Windows Phone
協議 | Windows Store/ .NET | Windows Store/ JavaScript | Windows Phone/ IE | Windows Phone/ .NET |
---|---|---|---|---|
WebSockets | N/A | Win8+ | 8+ | N/A |
Forever Frame | N/A | Win8+ | 7.5+ | N/A |
Server-Sent Events | Win8+ | N/A | N/A | 8+ |
Long Polling | Win8+ | Win8+ | 7.5+ | 8+ |
參考鏈接:
https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/introduction-to-signalr
https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/supported-platforms