【SignalR學習系列】1. SignalR理論介紹
什麼是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