1. 程式人生 > >ASP.NET Core的實時庫: SignalR簡介及使用

ASP.NET Core的實時庫: SignalR簡介及使用

SignalR

SignalR是一個.NET Core/.NET Framework的開源實時框架. SignalR的可使用Web Socket, Server Sent Events 和 Long Polling作為底層傳輸方式.

SignalR基於這三種技術構建, 抽象於它們之上, 它讓你更好的關注業務問題而不是底層傳輸技術問題.

SignalR這個框架分伺服器端和客戶端, 伺服器端支援ASP.NET Core 和 ASP.NET; 而客戶端除了支援瀏覽器裡的javascript以外, 也支援其它型別的客戶端, 例如桌面應用.

回落機制

SignalR使用的三種底層傳輸技術分別是Web Socket, Server Sent Events 和 Long Polling.

其中Web Socket僅支援比較現代的瀏覽器, Web伺服器也不能太老.

而Server Sent Events 情況可能好一點, 但是也存在同樣的問題.

所以SignalR採用了回落機制, SignalR有能力去協商支援的傳輸型別.

Web Socket是最好的最有效的傳輸方式, 如果瀏覽器或Web伺服器不支援它的話, 就會降級使用SSE, 實在不行就用Long Polling.

一旦建立連線, SignalR就會開始傳送keep alive訊息, 來檢查連線是否還正常. 如果有問題, 就會丟擲異常.

因為SignalR是抽象於三種傳輸方式的上層, 所以無論底層採用的哪種方式, SignalR的用法都是一樣的.

SignalR預設採用這種回落機制來進行傳輸和連線.

但是也可以禁用回落機制, 只採用其中一種傳輸方式.

RPC

RPC (Remote Procedure Call). 它的優點就是可以像呼叫本地方法一樣呼叫遠端服務.

SignalR採用RPC正規化來進行客戶端與伺服器端之間的通訊.

SignalR利用底層傳輸來讓伺服器可以呼叫客戶端的方法, 反之亦然, 這些方法可以帶引數, 引數也可以是複雜物件, SignalR負責序列化和反序列化.

Hub

Hub是SignalR的一個元件, 它執行在ASP.NET Core應用裡. 所以它是伺服器端的一個類.

Hub使用RPC接受從客戶端發來的訊息, 也能把訊息傳送給客戶端. 所以它就是一個通訊用的Hub.

在ASP.NET Core裡, 自己建立的Hub類需要繼承於基類Hub.

在Hub類裡面, 我們就可以呼叫所有客戶端上的方法了. 同樣客戶端也可以呼叫Hub類裡的方法.

這種Hub+RPC的方式還是非常適合實時場景的.

之前說過方法呼叫的時候可以傳遞複雜引數, SignalR可以將引數序列化和反序列化. 這些引數被序列化的格式叫做Hub 協議, 所以Hub協議就是一種用來序列化和反序列化的格式.

Hub協議的預設協議是JSON, 還支援另外一個協議是MessagePack. MessagePack是二進位制格式的, 它比JSON更緊湊, 而且處理起來更簡單快速, 因為它是二進位制的.

此外, SignalR也可以擴充套件使用其它協議..

橫向擴充套件

隨著系統的執行, 有時您可能需要進行橫向擴充套件. 就是應用執行在多個伺服器上.

這時負載均衡器會保證每個進來的請求按照一定的邏輯分配到可能是不同的伺服器上.

在使用Web Socket的時候, 沒什麼問題, 因為一旦Web Socket的連線建立, 就像在瀏覽器和那個伺服器之間打開了隧道一樣, 伺服器是不會切換的.

但是如果使用Long Polling, 就可能有問題了, 因為使用Long Polling的情況下, 每次傳送訊息都是不同的請求, 而每次請求可能會到達不同的伺服器. 不同的伺服器可能不知道前一個伺服器通訊的內容, 這就會造成問題.

針對這個問題, 我們需要使用Sticky Sessions (粘性會話).

Sticky Sessions 貌似有很多中實現方式, 但是主要是下面要介紹的這種方式.

作為第一次請求的響應的一部分, 負載均衡器會在瀏覽器裡面設定一個Cookie, 來表示使用過這個伺服器. 在後續的請求裡, 負載均衡器讀取Cookie, 然後把請求分配給同一個伺服器. 

在ASP.NET Core 中使用SignalR

建立專案

使用空模板建立ASP.NET Core專案.

建立一個CountService:

建立一個CountHub, 繼承於Hub:

配置SignalR

在Startup裡註冊SignalR:

如果需要的話可以在AddSignalR()這個方法裡使用lambda表示式進行一些配置.

然後在管道里使用SignalR, 使用app.UseSignalR():

這裡我已經建立了一個Hub, 叫做CountHub.

該方法的引數型別是Action<HubRouteBuilder>, 然後在這裡配置hub的路由.

使用Hub

首先建立一個Controller, 並注入IHubContext<CountHub>:

接下來我們就可以使用IHubContext<CountHub>這個物件與客戶端進行實時通訊了.

下面建立一個POST Action, 客戶端點選按鈕之後來到這個Action, 在這裡我們使用hub為所有的客戶端傳送一個訊息:

這裡, 我呼叫了所有客戶端上的someFunc這個方法, 引數是一個物件.

但是使用這種IHubContext<Hub>的注入方式, 我們無法在它那取得Caller(呼叫該方法的客戶端)這個屬性.

Context

從Hub的Context屬性, 我們可以獲得使用者的資訊.

我們在CountHub裡override父類的一個方法OnConnectedAsync():

如果有新的連線建立了, 這個方法就會被執行.

在Hub類裡, 我們可以訪問到Context屬性. 從Context屬性那, 我們可以獲得一個常用的屬性叫做ConnectionId. 這個ConnectionId就是連線到Hub的這個客戶端的唯一標識.

使用ConnectionId, 我們就可以取得這個客戶端, 並呼叫其方法, 如圖中的Clients.Client(connectionId).xxx.

Hub的Clients屬性表示客戶端, 它有若干個方法可以選擇客戶端, 剛才的Client(connectionId)就是使用connectionId找到這一個客戶端. 而AllExcept(connectionId)就是除了這個connectionId的客戶端之外的所有客戶端. 更多方法請檢視文件.

SignalR還有Group分組的概念, 而且操作簡單, 這裡用到的是Hub的Groups屬性. 向一個Group名新增第一個connectionId的時候, 分組就被建立. 移除分組內最後一個客戶端的時候, 分組就被刪除了. 使用Clients.Group("組名")可以呼叫組內客戶端的方法.

授權和驗證

SignalR會採用ASP.NET Core配置好的授權和驗證體系.

用法和Controller差不多:

想要取得User物件, 需要使用Context.User, 它的型別是ClaimsPrinciple:

客戶端

客戶端需要安裝signalr這個庫. 可以使用npm安裝 @aspnet/signalr

但是實際上只需要signalr.js一個檔案即可.

客戶端程式碼如下:

 

點選按鈕後先執行Controller的POST方法, POST返回的是Accepted(1), 所以id是1.

使用singalR物件的HubConnectionBuilder來構建connection. 使用返回的connection物件, 我們可以用它的on方法來處理伺服器端方法呼叫的響應. 響應方法的引數可以是簡單型別也可以是複雜的物件.

使用connection.start()來開啟連線, 使用catch()來捕獲異常, 使用connection.stop() 關閉連線.

先執行一下看看效果:

可以看到使用Clients.All, 所有的客戶端的方法都會被呼叫.

剛開啟頁面的時候, 我們就嘗試建立連線, 從F12可以看到一個叫做negotiate的請求被髮送了:

這個請求的body如下:

可以看到客戶端選擇了一個connectionId,  裡面還有瀏覽器支援的傳輸方式.

伺服器的響應:

響應也包含著connectionId, 以及伺服器支援的傳輸方式. 這裡三種都支援. 由於我沒有指定傳輸方式, 所以SignalR選擇了最好的方式: websocket.

而在我點選按鈕後, Web Socket連線才被初始化:

如果需要手動指定傳輸方式, 請在withUrl()方法的第二個引數指定傳輸方式: 

其它型別的客戶端

.NET 客戶端可以安裝 Microsoft.AspNetCore.SignalR.Client 這個包來支援SignalR.

具體用法請檢視官方文件, 語法和js的差不多.

MessagePack協議

需要安裝 Microsoft.AspNetCore.SignalR.Protocols.MessagePack.

然後在Startup裡面使用AddMessagePackProtocol()這個方法即可:

這樣的話, 伺服器端既支援JSON, 也支援MessagePack了.

另外.NET客戶端也需要安裝這個MessagePack包.

而js客戶端需要安裝 @aspnet/signalr-protocol-msgpack.

橫向擴充套件 Scale-out

可以採用Redis, 需要安裝 Microsoft.AspNetCore.SignalR.Redis. 這個包.

然後在Startup裡面配置:

這個沒試過, 請看官方文件.

SignalR就介紹這些....

相關推薦

ASP.NET Core實時: SignalR簡介使用

SignalR SignalR是一個.NET Core/.NET Framework的開源實時框架. SignalR的可使用Web Socket, Server Sent Events 和 Long Polling作為底層傳輸方式. SignalR基於這三種技術構建, 抽

Asp.net core實戰2: 開發工具常用指令

如果你願意,完全可以使用notepad進行開發,不過也有可用的IDE推薦 1.visual Studio 這款視覺化的微軟神器當然是支援net core的啦! 2. visual studio code 這款跨平臺開發工具, 可以說是神器了.支援mac,linus,w

Asp.net core 學習筆記 SignalR

refer :  https://kimsereyblog.blogspot.com/2018/07/signalr-with-asp-net-core.html https://github.com/aspnet/AspNetCore/issues/5155   跟著官網 ste

Asp.Net Core 中IdentityServer4 授權原理重新整理Token的應用

## 一、前言 上面分享了`IdentityServer4` 兩篇系列文章,核心主題主要是`密碼授權模式`及`自定義授權模式`,但是僅僅是分享了這兩種模式的使用,這篇文章進一步來分享`IdentityServer4`的授權流程及`refreshtoken`。 系列文章目錄(**沒看過的先看這幾篇文章再來閱

Asp.Net Core AuthorizeAttribute 和AuthorizeFilter 跟進原始碼解讀

一、前言 IdentityServer4已經分享了一些應用實戰的文章,從架構到授權中心的落地應用,也伴隨著對IdentityServer4掌握了一些使用規則,但是很多原理性東西還是一知半解,故我這裡持續性來帶大家一起來解讀它的相關原始碼,本文先來看看為什麼Controller或者Action中新增Author

Log4net 的 ASP.NET Core 擴充套件

給大家安利一款 `log4net` 的 ASP.NET Core 擴充套件庫,它是基於 `log4net` 開發的。 簡單易用,開源免費,使用ASP.NET Core自身提供的DI容器來實現服務的註冊和消費。直接在程式啟動時註冊到服務中即可完成全部配置,對於小白使用者也可快速上手 log4net 日誌元件。

ASP.NET Core擴充套件

親愛的.Neter們,在我們日復一日的編碼過程中是不是會遇到一些讓人煩惱的事情: 日誌配置太過複雜,各種模板、引數也搞不清楚,每次都要去檢視日誌庫的文件,還需要複製貼上一些重複程式碼,好無賴 當需要型別轉換時,使用AutoMapper時感覺配置又複雜,自己寫人肉轉換程式碼又冗長,又枯燥,好無聊 當呼叫其他服

ASP.NET Core擴充套件之日誌

    上一篇我們對Xfrogcn.AspNetCore.Extensions擴充套件庫功能進行了簡單的介紹,從這一篇文章開始,我將逐步介紹擴充套件庫中的核心功能。     日誌作為非業務的通用領域基礎功能,有非常多的技術實現,這些第三方庫避免了我們花費時間去重複實現,

ASP.NET Core實時: SignalR -- 預備知識

大綱 本系列會分為2-3篇文章. 第一篇介紹SignalR的預備知識和原理 然後會介紹SignalR和如何在ASP.NET Core裡使用SignalR. 本文的目錄如下: 實時Web簡述 大家都見過和用過實時Web, 例如網頁版的即時通訊工具, 網頁直播, 網頁遊戲, 還有股

Asp.Net Core + SignalR 實現實時通訊

一、搭建專案 1、建立一個ASP.NET Core MVC 專案   2、nuget 下載和安裝 MicroSoft.AspNetCore.SignalR vs提示版本衝突 這時我們選擇低版本即可 二、SignalR配置 1、在model中建立一個類MyHub 程式

asp.net core 抽取Controller到類Autofac自動屬性注入

寫在前面  之前有個專案是用asp.net webapi做的,pc和移動端共用api的服務介面,balabala,正好最近在看關於asp.net core方面的資料,各種依賴注入,中介軟體,處理管道等,而且把webapi和mvc融合到了一起,就想著把之前那個專案移到asp.net cor

ASP.Net Core 3.1 使用實時應用SignalR入門

參考文章:微軟官方文件:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/introduction?view=aspnetcore-3.1 和 https://www.cnblogs.com/cgzl/p/9509207.html 系列 ASP

ASP.NET Core實現類項目讀取配置文件

services 應用程序 配置文件 builder public .NET Core類庫項目讀取JSON配置文件在應用程序目錄下添加JSON文件是進行如下配置: var builder = new ConfigurationBuilder()

ASP.NET Core之跨平臺的實時性能監控

js應用程序的8個關鍵性能指標以及測量方法最後賣了個小關子,是關於如何監控ASP.NET Core的.今天我們就來講講如何監控它,下面上效果圖: 閱讀本文需要了解的相關技術與內容:InfluxDb(分布式時序數據庫,開源)(註:分布式部分已商業化最新的分布式版本已不在開源,單例的繼續開源)Grafana(開源

Asp.net Core 2.0連接mysql數據一系列錯誤問題

alt sql mysql mysql數據庫 work image sql數據庫 報錯 entity mysql:最新版 一定是最新版,不然各種報錯 Install-Package Pomelo.EntityFrameworkCore.MySql 2.0.0-rtm-100

一起學ASP.NET Core 2.0學習筆記(二): ef core2.0 mysql provider 、Fluent API相關配置遷移

upd order rac option 包管理 rtl code create .net core 不得不說微軟的技術叠代還是很快的,上了微軟的船就得跟著她走下去,前文一起學ASP.NET Core 2.0學習筆記(一): CentOS下 .net core2 s

asp.net core 2.0 webapi集成signalr

soft onf everyone text hosting tro 不能 .com fault 在博客園也很多年了,一直未曾分享過什麽東西,也沒有寫過博客,但自己也是汲取著博客園的知識成長的; 這兩天想著不能這麽無私,最近.NET CORE貌似挺流行的,

ASP.NET CORE 2.0使用SignalR技術

cli put ast log body post disco nbsp dot 閱讀目錄 一、前言 二、環境搭建 三、最後 回到目錄 一、前言 上次講SignalR還是在《在ASP.NET Core下使用SignalR技術》文章中提到,ASP.NET Core 1

asp.net core 通過ajax上傳圖片wangEditor圖片上傳

images use class multi jquery 開始 load als org asp.net core 通過ajax上傳圖片 .net core前端代碼,因為是通過ajax調用,首先要保證ajax能調用後臺代碼,具體參見上一篇.net core 使用ajax

ASP.NET MVC應用遷移到ASP.NET Core及其異同簡介

連接 項目引用 asi ane 隨著 efm 什麽 數據庫的配置 自動   ASP.NET Core是微軟新推出支持跨平臺、高性能、開源的開發框架,相比起原有的ASP.NET來說,ASP.NET Core更適合開發現代應用程序,如跨平臺、Dorker的支持、集成現代前端開發