歡迎光臨
每天分享高質量文章

.NET Core SignalR 初體驗

作者:丶Pz

鏈接:http://www.cnblogs.com/panzi/p/9649315.html

前言


ASP.NET SignalR已經出來很久了,但是一直沒有靜下心來好好看看。

花了幾個小時的時間看了下。

首先借鑒了官方文件,如何搭建一個SignalR的Demo。

參考文章:https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?view=aspnetcore-2.1&tabs;=visual-studio 

SignalR地址:https://github.com/aspnet/SignalR

所以為了快速搭建和體驗.Net Core版本的SignalR,我選擇了下載官方的Demo和參考官方給的教程。所以具體的搭建過程我就不再本文中寫了。

體驗效果


官網給出的DEMO運行如下圖:

點擊connect,查看一下network。可以發現,它在當前瀏覽器支持三種方式。

而且和.NET Framework版本不同的是,新版SignalR中的Hub型別也是蠻豐富的。Demo中給出了 普通Hub,DynamicHub,Hub 三種型別。我們去看看其中的區別吧。

普通Hub

查看定義,可以看到普通Hub中的Clients型別是 IHubCallerClients 

namespace Microsoft.AspNetCore.SignalR

{

    //

    // 摘要:

    //     A base class for a SignalR hub.

    public abstract class Hub : IDisposable

    {

        protected Hub();

 

        //

        // 摘要:

        //     Gets or sets an object that can be used to invoke methods on the clients connected

        //     to this hub.

        public IHubCallerClients Clients { get; set; }

        //

        // 摘要:

        //     Gets or sets the hub caller context.

        public HubCallerContext Context { get; set; }

        //

        // 摘要:

        //     Gets or sets the group manager.

        public IGroupManager Groups { get; set; }

 

        //

        public void Dispose();

        //

        // 摘要:

        //     Called when a new connection is established with the hub.

        //

        // 傳回結果:

        //     A System.Threading.Tasks.Task that represents the asynchronous connect.

        public virtual Task OnConnectedAsync();

        //

        // 摘要:

        //     Called when a connection with the hub is terminated.

        //

        // 傳回結果:

        //     A System.Threading.Tasks.Task that represents the asynchronous disconnect.

        public virtual Task OnDisconnectedAsync(Exception exception);

        //

        // 摘要:

        //     Releases all resources currently used by this Microsoft.AspNetCore.SignalR.Hub

        //     instance.

        //

        // 引數:

        //   disposing:

        //     true if this method is being invoked by the Microsoft.AspNetCore.SignalR.Hub.Dispose

        //     method, otherwise false.

        protected virtual void Dispose(bool disposing);

    }

}

IHubCallerClients 定義如下:

public interface IHubCallerClients : IHubCallerClients, IHubClients

{

}

而框架又給IClientProxy增加了擴展方法:SendAsync

所以在普通Hub中,定義客戶端方法的時候,需要把方法名當作引數傳入SendAsync方法中。例如如下代碼:

public Task Send(string message)

{

    return Clients.All.SendAsync(“Receive”, $”{Context.ConnectionId}: {message}”);

}

DynamicHub

DynamicHub我是比較喜歡的,因為他和 Framework版的是一樣(或者說看起來是一樣的)的。動態Hub我們就可以不必拘泥於只能呼叫SendAsync方法了。例如:

public Task SendToOthers(string message)

{

    return Clients.Others.ThisIsMyReceiveMethod($”{Context.ConnectionId}: {message}”);

}

DynamicHub的Clients型別為:DynamicHubClients ,它的內部變數全都是dynamic型別的。

Hub

泛型Hub就把規約交給開發者制定。在Demo中 Hub 中的IChatClient接口定義了Receive方法,因此Clients中的物件可以呼叫Receive方法。同理,我們可以根據業務需要定義自己的方法。至少從代碼上看會顯得更加通俗易懂一些。比如:

public interface IChatClient

{

    Task Receive(string message);

    Task LoginSuccess(long userId);

}

public Task Login(long userId)

{

    return Clients.Caller.LoginSuccess(userId);

}

其實從代碼上來看的話,他們都是Hub,只不過是不同的擴展實現而已。而泛型Hub不過是用戶自定義泛型接口,而預設Hub中的預設泛型接口為:IClientProxy.所以看到這裡,如果我就想使用原生的Hub而又想自定義方法怎麼辦呢?很簡單,加擴展就可以了。

為什麼自己加就可以呢,其實 SendAsync 就是擴展方法,它內部也是呼叫了SendCoreAsync方法。於是乎,寫下自己的擴展方法,那這樣子就很靈活了。我們把method引數去掉,直接寫死試試:

public static Task LoginAsync(this IClientProxy clientProxy, string message, CancellationToken cancellationToken = default(CancellationToken))

{

    return clientProxy.SendCoreAsync(“LoginSuccess”, new object[] { message}, cancellationToken);

}

其實說白了,這個擴展方法還是需要傳入method引數的,只不過封裝了一層(似乎感覺這麼做有意義嗎?哈哈,還是老老實實用泛型吧),那麼我們在去看Hub中的方法,修改Send方法如下:

public Task Send(string message)

{

    return Clients.All.LoginAsync($”{Context.ConnectionId}: {message}”);

}

是不是這樣子就實現了自己自定義方法了呢?個人覺得這麼寫還繞了一圈,不如用泛型或者Dynamic了。

運行一下,看看效果:

其實我也是抱著試試的態度,沒想到還真是這樣,和新方法就是SendCoreAsync,而其他方法只不過是上層封裝使得代碼更加通俗易懂。

使用Redis

Demo中的其他例子就不再演示了。廣播,一對一,一對多,加入組,退出組等基本和之前一樣。這裡在演示一下使用Redis做不同實體之間的通信效果。

首先程式集是不能少的:Microsoft.AspNetCore.SignalR.Redis,然後在Startup中補充代碼:

打開Redis客戶端,使用MONITOR命令監聽一下,從程式啟動,到連接,在發送一條廣播訊息:hello redis。  redis 監聽結果如下:

所以,PUB/SUB還是立了大功呢。

這裡用CMD運行了兩個實體,端口分別為 8881,8882來模擬兩個站點。

演示效果如下:

沒問題的哦,其實仔細想想,雖然運行了兩個網站實體,但是連接信息都儲存在同一個Redis上,那肯定通信是木的問題的啦。

總結

只是簡單的運行了一下DEMO,大致瞭解了一下 .NET Core SignalR的表層,至少跑Demo是跑起來了,並且使用Redis也是沒有問題的。

不過好像會出現運行一旦時間,程式自動停掉的問題,不知道是不是我電腦的問題。

本文代碼地址:https://github.com/fanpan26/LayIM.AspNetCore/tree/master/src/LayIM.AspNetCore.Demo/SignalRSamples


●編號154,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

Web開發

更多推薦18個技術類公眾微信

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂