天天看點

SignalR簡介

ASP.NET SignalR是ASP.NET開發人員的庫,它簡化了向應用程式添加實時Web功能的過程。實時網絡功能可以讓伺服器代碼在連接配接的用戶端可用時立即将内容推送到連接配接的用戶端,而不是讓伺服器等待用戶端請求新資料。

SignalR可以用于向ASP.NET應用程式添加任何類型的“實時”Web功能。雖然聊天通常被用作一個例子,你可以做更多。每當使用者重新整理網頁以檢視新資料,或者頁面實作長輪詢以檢索新資料時,它是使用SignalR的候選。示例包括儀表闆和監視應用程式,協作應用程式(如同時編輯文檔),作業進度更新和實時表單。

SignalR還支援需要從伺服器進行高頻更新的全新類型的Web應用程式,例如實時遊戲。有關這方面的一個很好的例子,請參閱ShootR遊戲。

SignalR提供了一個用于建立從伺服器端.NET代碼調用用戶端浏覽器(和其他用戶端平台)中的JavaScript函數的伺服器到用戶端遠端過程調用(RPC)的簡單API。SignalR還包括用于連接配接管理(例如,連接配接和斷開事件)的API和分組連接配接。

SignalR簡介

SignalR自動處理連接配接管理,并允許您同時向所有連接配接的用戶端廣播消息,如聊天室。您還可以向特定用戶端發送消息。用戶端和伺服器之間的連接配接是持久的,不像為每個通信重建立立的傳統HTTP連接配接。

SignalR支援“伺服器推送”功能,其中伺服器代碼可以使用遠端過程調用(RPC)在浏覽器中調用用戶端代碼,而不是當今Web上常見的請求 - 響應模型。

SignalR應用程式可以使用Service Bus,SQL Server或Redis擴充到數千個用戶端。

SignalR是開源的,可通過GitHub通路。

SignalR在可用時使用新的WebSocket傳輸,并在必要時回退到舊的傳輸。雖然你可以直接使用WebSocket編寫你的應用程式,但使用SignalR意味着你需要實作的很多額外的功能已經為你完成了。最重要的是,這意味着您可以編寫應用程式以利用WebSocket,而無需擔心為較舊的用戶端建立單獨的代碼路徑。SignalR還屏蔽了您不必擔心WebSocket的更新,因為SignalR将繼續更新以支援底層傳輸中的更改,進而為您的應用程式提供跨WebSocket版本的一緻性界面。

雖然你當然可以單獨使用WebSocket建立一個解決方案,SignalR提供了你自己需要的所有功能,例如回退到其他傳輸和修改你的應用程式更新WebSocket實作。

SignalR是對用戶端和伺服器之間進行實時工作所需的一些傳輸的抽象。SignalR連接配接以HTTP開頭,然後更新到WebSocket連接配接(如果可用)。WebSocket是SignalR的理想傳輸,因為它可以最高效地使用伺服器記憶體,具有最低的延遲,并且具有最底層的功能(如用戶端和伺服器之間的全雙工通信),但它也具有最嚴格的要求:WebSocket要求伺服器使用Windows Server 2012或Windows 8以及.NET Framework 4.5。如果不滿足這些要求,SignalR将嘗試使用其他傳輸進行連接配接。

這些傳輸依賴于對HTML 5的支援。如果用戶端浏覽器不支援HTML 5标準,将使用舊的傳輸。

WebSocket(如果伺服器和浏覽器都訓示他們可以支援Websocket)。WebSocket是唯一的在用戶端和伺服器之間建立真正的持久性,雙向連接配接的傳輸。但是,WebSocket也有最嚴格的要求; 它僅在最新版本的Microsoft Internet Explorer,Google Chrome和Mozilla Firefox中完全受支援,并且僅在其他浏覽器(如Opera和Safari)中部分實作。

伺服器發送的事件,也稱為EventSource(如果浏覽器支援伺服器發送事件,這基本上是除Internet Explorer之外的所有浏覽器)。

以下傳輸基于Comet Web應用程式模型,其中浏覽器或其他用戶端維護長期保留的HTTP請求,伺服器可以使用該請求将資料推送到用戶端,而用戶端沒有明确請求它。

Forever架構(僅限Internet Explorer)。Forever Frame建立一個隐藏的IFrame,它向伺服器上的一個端點發出一個未完成的請求。伺服器然後不斷地向用戶端發送腳本,該腳本被立即執行,提供從伺服器到用戶端的單向實時連接配接。從用戶端到伺服器的連接配接使用從伺服器到用戶端連接配接的單獨連接配接,并且像标準HTML請求一樣,為需要發送的每個資料段建立新連接配接。

Ajax長輪詢。長輪詢不會建立持久連接配接,而是輪詢伺服器并保持打開的請求,直到伺服器響應,此時連接配接關閉,并立即請求新連接配接。這可能會在連接配接重置時引入一些延遲。

有關哪些配置支援什麼傳輸的詳細資訊,請參閱支援的平台。

以下清單顯示SignalR用于決定使用哪個傳輸的步驟。

如果浏覽器是Internet Explorer 8或更早版本,則使用長輪詢。

如果配置了JSONP(即,連接配接<code>jsonp</code>啟動時将參數設定為<code>true</code>),則使用長輪詢。

如果正在進行跨域連接配接(即,如果SignalR端點與主機頁不在同一個域中),則将在滿足以下條件時使用WebSocket:

用戶端支援CORS(跨源資源共享)。有關哪些用戶端支援CORS的詳細資訊,請參閱caniuse.com上的CORS。

用戶端支援WebSocket

伺服器支援WebSocket

如果不滿足任何這些标準,将使用長輪詢。有關跨域連接配接的詳細資訊,請參閱如何建立跨域連接配接。

如果未配置JSONP并且連接配接不是跨域,則如果用戶端和伺服器都支援WebSocket,則将使用WebSocket。

如果用戶端或伺服器不支援WebSocket,則使用“伺服器已發送事件”(如果可用)。

如果伺服器發送的事件不可用,嘗試永久幀。

如果Forever Frame失敗,則使用長輪詢。

您可以通過在集線器上啟用日志記錄并在浏覽器中打開控制台視窗來确定應用程式正在使用的傳輸方式。

要在浏覽器中啟用集線器事件的日志記錄,請将以下指令添加到用戶端應用程式:

<code>$.connection.hub.logging = true;</code>

在Internet Explorer中,按F12打開開發人員工具,然後單擊控制台頁籤。

SignalR簡介

在Chrome中,按Ctrl + Shift + J打開控制台。

SignalR簡介

打開控制台并啟用日志記錄後,您将可以看到SignalR正在使用哪個傳輸。

SignalR簡介

+

協商傳輸需要一定的時間和用戶端/伺服器資源。如果用戶端能力已知,則可以在用戶端連接配接啟動時指定傳輸。以下代碼片段示範了使用Ajax Long Polling傳輸啟動連接配接,如果知道用戶端不支援任何其他協定,則使用該代碼:

<code>connection.start({ transport: 'longPolling' });</code>

如果您希望用戶端按順序嘗試特定傳輸,則可以指定回退順序。以下代碼片段示範了嘗試WebSocket,并且失敗,直接轉到長輪詢。

<code>connection.start({ transport: ['webSockets','longPolling'] });</code>

用于指定傳輸的字元串常量定義如下:

<code>webSockets</code>

<code>foreverFrame</code>

<code>serverSentEvents</code>

<code>longPolling</code>

SignalR API包含兩個用于用戶端和伺服器之間通信的模型:持久連接配接和集線器。

連接配接表示用于發送單收件人,分組或廣播郵件的簡單端點。持久連接配接API(由PersistentConnection類在.NET代碼中表示)使開發人員能夠直接通路SignalR公開的低級通信協定。使用Connections通信模型對于使用基于連接配接的API(如Windows Communcation Foundation)的開發人員來說很熟悉。

Hub是一個建構在Connection API上的更進階别的管道,允許您的用戶端和伺服器直接互相調用方法。SignalR處理跨機器邊界的排程,就像通過魔法,允許用戶端像伺服器本地方法一樣輕松地調用方法,反之亦然。使用遠端調用API(例如.NET Remoting)的開發人員将熟悉使用Hubs通信模型。使用Hub還允許您将強類型參數傳遞給方法,進而啟用模型綁定。

下圖顯示了集線器,持久連接配接和用于傳輸的基礎技術之間的關系。

SignalR簡介

當伺服器端代碼在用戶端上調用一個方法時,将通過活動傳輸發送一個包,其中包含要調用的方法的名稱和參數(當對象作為方法參數發送時,将使用JSON序列化)。然後,用戶端将方法名稱與用戶端代碼中定義的方法進行比對。如果存在比對,則将使用反序列化的參數資料來執行用戶端方法。

可以使用諸如Fiddler的工具來監視方法調用。下圖顯示了從Fiddler的Logs窗格中的SignalR伺服器發送到Web浏覽器用戶端的方法調用。方法調用從<code>MoveShapeHub</code>被調用的集線器發送,并且調用被調用的方法<code>updateShape</code>。

SignalR簡介

1

在此示例中,集線器名稱用<code>H</code>參數辨別; 方法名稱用<code>M</code>參數辨別,并且發送到方法的資料用<code>A</code>參數辨別。生成此消息的應用程式在高頻實時教程中建立。

大多數應用程式應使用Hubs API。Connections API可用于以下情況:

必須指定發送的實際消息的格式。

開發人員更喜歡使用消息傳遞和排程模型,而不是遠端調用模型。

使用消息傳遞模型的現有應用程式正在移植以使用SignalR。