SignalR 簡介

SignalR 簡介javascript

帕特里克 · 弗萊徹|2013 年 2 月 27 日java

英文原文地址:http://www.asp.net/signalr/overview/getting-started/introduction-to-signalrweb

這篇文章描述 SignalR 是什麼,和一些它旨在建立的解決方案。redis

SignalR 是什麼?

ASP.NET SignalR 是爲 ASP.NET 開發人員提供的一個庫,能夠簡化開發人員將實時 Web 功能添加到應用程序的過程。實時 Web 功能是指這樣一種功能:當所鏈接的客戶端變得可用時服務器代碼能夠當即向其推送內容,而不是讓服務器等待客戶端請求新的數據。json

SignalR 能夠用於將任何種類的「實時」Web 功能添加到您的 ASP.NET 應用程序。雖然咱們常常把聊天應用做爲最經常使用的一個例子,但實際上你能夠利用它作不少事情。若是用戶是經過刷新 web 頁面,來查看新的數據,或者是經過頁面實現長輪詢來檢索新的數據,那麼就該考慮使用 SignalR 了。示例包括儀表板和監視應用程序、協做應用程序(例如同時編輯文檔)、工做進度更新和實時表單等等。api

SignalR 還適用於全新類型的 Web 應用程序,特別是須要從服務器高頻率更新的應用程序,例如實時遊戲。一個好的例子,請參閱ShootR 遊戲。跨域

SignalR 提供一個簡單的 API 用於建立服務器端到客戶端的遠程過程調用 (RPC),以便從服務器端 .NET 代碼中調用客戶端瀏覽器(以及其餘客戶端平臺)中的 JavaScript 函數。SignalR 還包括用於管理鏈接(例如,鏈接和斷開鏈接事件)和爲鏈接分組的 API。瀏覽器

Invoking methods with SignalR

SignalR 會自動管理鏈接,並容許您像聊天室那樣向全部鏈接的客戶端同時發送消息。你也能夠向特定的客戶端發送消息。客戶端和服務器之間的鏈接是持久性的,不像傳統的 HTTP 鏈接 —— 每一個通訊都須要從新創建一個鏈接。服務器

SignalR 支持「服務器推送」功能,即服務器代碼可使用遠程過程調用 (PRC) 來調用瀏覽器中的客戶端代碼,而不使用目前在 Web 上經常使用的請求-響應模型。asp.net

SignalR 應用程序能夠經過使用服務總線、SQL Server 或 Redis 擴展到數以千計的客戶端.

SignalR 是開源的,能夠經過 GitHub 訪問。

SignalR 和 WebSocket

SignalR 會在可能的狀況下使用新的 WebSocket 傳輸方式,而且在須要時回退到舊的傳輸方式。雖然您仍然能夠直接使用 WebSocket 來編寫應用程序,可是使用 SignalR 意味着您有許多現成的額外功能可用,而無需本身實現這些功能。最重要的是,這意味着您可使用 SignalR 編寫應用程序以利用 WebSocket,而無需擔憂爲舊的客戶端單首創建代碼。SignalR 還可以使你沒必要擔憂 WebSocket 的更新,由於 SignalR 會持續更新以支持基礎傳輸方式的更改,爲您的應用程序提供一致的接口以使用不一樣的 WebSocket 版本。

固然,您能夠建立只使用 WebSocket 的解決方案,SignalR 爲您提供了可能須要自行編寫代碼的全部功能,例如回退到其餘的傳輸方式以及修訂您的應用程序以更新到 WebSocket 實現。

傳輸和回退

SignalR 是對一組在構建客戶端和服務器之間的real-time功能所須要使用的傳輸技術的抽象。SignalR 鏈接首先以 HTTP 發起請求,而後若是 WebSocket 可用的話,則升級到 WebSocket 鏈接。WebSocket 是 SignalR 的理想傳輸方式,由於它可以最高效地使用服務器的內存、 有最低的延遲,並且有的最主要的功能(如客戶端和服務器之間的全雙工通訊),但它也有最嚴格的環境需求: WebSocket 要求服務器是 Windows Server 2012 或 Windows 8 以及.NET Framework 4.5。若是不知足這些要求,SignalR 將嘗試使用其餘傳輸方式來創建鏈接。

HTML 5 傳輸

傳輸方式取決因而否支持 HTML 5。若是客戶端瀏覽器不支持 HTML 5 標準,將使用較舊的傳輸方式。

  • WebSocket(若是服務器和瀏覽器都指明它們支持 Websocket)。WebSocket 是惟一一個在客戶端和服務器之間創建真正的持久雙向鏈接的傳輸方式。然而,WebSocket 也有最嚴格的要求 ;只有最新版本的 Microsoft Internet Explorer、Google Chrome 和 Mozilla Firefox 徹底支持,其餘瀏覽器如 Opera 和 Safari 只有部分實現。

  • 服務器發送事件,也稱爲 EventSource (若是瀏覽器支持服務器發送事件,基本上除了 Internet Explorer 以外其餘的瀏覽器都支持此功能)。

Comet 傳輸

下列傳輸基於 Comet Web 應用程序模型,在該模型中有一個瀏覽器或其餘客戶端維護着一個長時間的 HTTP 請求,服務器能夠在客戶端沒有明確請求的狀況下使用此請求將數據推送到客戶端。

  • Forever Frame(僅限 Internet Explorer)。Forever Frame 會建立一個隱藏的 IFrame,對服務器上的終結點發送一個不完整的請求。而後服務器不斷地發送腳本到客戶端,而且當即執行這些腳本,從而創建一個從服務器到客戶端的單向實時鏈接。從客戶端到服務器的鏈接使用的是不一樣於服務器到客戶端的鏈接,就像一個標準的 HTML 請求,對於每一個須要發送的數據都會建立一個新鏈接。

  • Ajax 的長輪詢。長輪詢不會建立一個持久性鏈接,而是經過一個請求來輪詢服務器,使鏈接保持打開狀態直到服務器發出響應,這時候再關閉該鏈接,而後當即請求一個新的鏈接。這可能會在鏈接重置時產生一些延遲。

有關各類配置所支持的傳輸方式的詳細信息,請參見支持的平臺.

傳輸方式選擇過程

下面的列表顯示 SignalR 決定使用的傳輸方式的步驟。

  1. 若是瀏覽器是 Internet Explorer 8 或更早版本,則使用長輪詢。

  2. 若是配置了 JSONP (即鏈接啓動時jsonp參數設置爲true ),則使用長輪詢。

  3. 若是正在使用跨域的鏈接 (即 SignalR 終結點和宿主頁不在相同的域中),而且符合如下的條件將使用 WebSocket :

    • 客戶端支持 CORS (Cross-Origin Resource Sharing)。哪一種客戶端支持 CORS 的詳細信息,請參閱在 caniuse.com CORS.

    • 客戶端支持 WebSocket

    • 服務器支持 WebSocket

    若是這些標準中的任何一條不知足,將使用長輪詢。跨域鏈接的詳細信息,請參閱如何創建跨域的鏈接.

  4. 若是不配置爲使用 JSONP 、鏈接不跨域而且客戶端和服務器都支持,將使用 WebSocket 。

  5. 若是客戶端或服務器不支持 WebSocket,則儘可能使用服務器發送事件。

  6. 若是服務器發送事件不可用,則將嘗試使用 Forever Frame。

  7. 若是 Forever Frame 不可用,則使用長輪詢。

Monitoring 傳輸方式

您能夠經過在您的應用程序hub啓用日誌記錄,並在您的瀏覽器的控制檯窗口中查看您的應用程序使用哪一種傳輸協議。

將下面的命令添加到您的客戶端應用程序,以在瀏覽器中啓用hub事件的日誌記錄:

$.connection.myHub.logging = true;

  • 在IE中,經過按 f12 鍵,能夠打開開發人員工具,而後單擊控制檯選項卡。

    Console in Microsoft Internet Explorer

  • 在 Chrome,按下 Ctrl + Shift + J 打開控制檯。

    Console in Google Chrome

經過控制檯的日誌記錄,你就可以看到 SignalR 正在使用的傳輸協議。

Console in Internet Explorer showing WebSocket transport

指定傳輸協議

使用固定的傳輸協議須要必定的時間和客戶端以及服務器的資源。若是客戶端環境已知,那麼當啓動客戶端鏈接時就能夠指定傳輸協議。下面的代碼段演示如何在已知客戶端不支持任何其餘協議時,直接在鏈接開始時就使用 Ajax 的長輪詢:

connection.start({ transport: 'longPolling' });

若是你想要一個客戶端按照特定順序嘗試傳輸方式,您能夠指定嘗試的順序。下面的代碼段演示如未嘗試使用 WebSocket 而且在失敗的時間去直接使用長輪詢。

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

用於指定傳輸方式的字符串常量的定義以下:

  • webSockets

  • forverFrame

  • serverSentEvents

  • longPolling

鏈接和Hubs

SignalR API 包含兩種客戶端和服務器之間進行通訊的模型: 永久鏈接和Hubs。

鏈接表示爲一個發送單個、 編組或廣播消息的簡單終結點。開發人員可使用持久性鏈接 API(在.NET 代碼中由 PersistentConnection 類表示)直接訪問 SignalR 公開的底層通訊協議的 。使用過基於鏈接 Api 好比wcf的開發人員會更加熟悉鏈接通訊模型。

Hub是基於鏈接 API的可是更高級別的通訊管線,它容許客戶端和服務器上彼此直接調用方法。SignalR 可以很神奇地處理跨機器的調度,使得客戶端可以調用在服務器上的方法就像輕鬆地調用本地方法,反之亦然。使用過基於遠程調用的 Api好比 .NET Remoting的開發人員會更加熟悉 Hubs通訊模型。使用Hub還容許您將強類型的參數傳遞給方法而且綁定模型。

體系結構關係圖

下面的關係圖顯示了Hub、 持續鏈接和用於傳輸的基礎技術之間的關係。

intro_architecture.png?cdn_id=2013-10-03

Hub的工做原理

當服務器端代碼調用客戶端上的方法時,服務器發送一個數據包其中包含的要調用的方法的名稱與參數(當被髮送的方法參數包含對象時,它將被序列化爲 JSON)。而後,客戶端經過方法的名稱在客戶端代碼中定義的方法中嘗試匹配。若是匹配成功,則將執行客戶端方法而且使用通過反序列化的參數數據。

可使用Fiddler之類的工具監視方法的調用。下圖顯示了Fiddler的日誌窗格中從 SignalR 的服務器發送到 web 瀏覽器客戶端的方法調用。從Hub發起調用的方法稱爲MoveShapeHub,被調用的方法是updateShape.

View of Fiddler log showing SignalR traffic

在此示例中,集線器名稱使用參數H 標識;方法名稱使用參數M標識,同時正在發送給該方法的數據使用參數A標識。生成此消息的應用程序是在High-Frequency Realtime教程中建立的。

選擇通訊模型

大多數應用程序應使用Hub的 API。鏈接 API 可用於如下狀況:

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

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

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

相關文章
相關標籤/搜索