Asp.Net Core SignalR 用泛型Hub優雅的調用前端方法及傳參

來源:互聯網
上載者:User
繼續學習

最近一直在使用Asp.Net Core SignalR(下面成SignalR Core)為小程式提供websocket支援,前端時間也發了一個學習筆記,在使用過程中稍微看了下它的源碼,不得不說微軟現在真的強大,很多事情都幫你考慮到了,比如使用Redis,使用Redis後,你的websocket就支援橫向擴充了,使用的方式也特別簡單,只需要在services.AddSignalR的後面再加上:

.AddRedis(options =>{    options.Configuration.ConnectTimeout = 30;    options.Configuration.EndPoints.Add("redis ip");})

SignalR Core利用了Redis的發布訂閱功能,就實現了橫向擴充,再也不用擔心一台ws伺服器不夠用了.

今天要說的並不是SignalR Core的負載平衡方式,而是如何優雅的調用前端方法。大家都知道SignalR Core除了可以建立websocket串連,還能雙向調用,伺服器調用用戶端方法,用戶端也能調用伺服器的方法。

原始調用

我們看下如何調用用戶端方法:

public class ChatHub : Hub{    //服務端方法    public async Task SendMessage(string user, string message)    {        //ReceiveMessage 為用戶端方法,讓所有用戶端調用這個方法        await Clients.All.SendAsync("sayHello", user, message);    }}

還是ChatHub~~~~~

我們可以看到在這裡我們調用了用戶端的sayHello,並傳遞了兩個字串參數user,message,是不是覺得醜陋,說實在的真心看不下去哈。而且不變維護,相當於你要把方法名寫入程式碼,傳遞多少個參數也沒有個准,沒有好的文檔後期很難維護。好在微軟已經為我們考慮到了這個情況,我們可以把用戶端的方法用介面的方法定義了!!!對!沒錯,用介面的方式定義用戶端的方法!!

優雅調用

使用的方式也超級簡單,我們先定義一個用戶端的介面:

public interface IMyClient{    Task SayHello(string user, string message);}

然後我們的Hub整合Hub,T就是你定義的用戶端介面,這裡也就是IMyClient,我用上面的ChatHub舉例:

public class SendMessageHub : Hub<IMyClient>{    public async Task SendMessage(string user, string message)    {        await this.Clients.All.SayHello(user, "from server:" + message);        //ReceiveMessage 為用戶端方法,讓所有用戶端調用這個方法        //await Clients.All.SendAsync("sayHello", user, message);    }}

注釋掉的是我之前的方式,SayHello是用戶端的方法,會通過websocket傳遞到前端,為我用小程式通訊產生的結果:

是不是SoEasy??我覺得還不算完,我們參數目前是按照數組的方式傳遞的,如果有限定的參數名就完美了,我們改造下IMyClient:

public interface IMyClient{    Task SayHello(HelloMessage message);}public class HelloMessage{    public string User { get; set; }    public string Message { get; set; }}

修改下我們的Hub的SendMessage方法:

public  Task SendMessage(string user, string message){    return this.Clients.All.SayHello(new HelloMessage()    {        User = user,        Message = "from server:" + message    });    //return this.Clients.All.SendAsync("sayHello", $"from server:{message}");}

在運行下我們的小程式:

LooK,方法名沒有改變,但是我們返回的參數成了一個對象,如果看過我之前那篇博文的話,應該記得在前端的時候,我需要做一個映射,來調用前端的方法,在映射中,我參數使用的是數組進行傳遞的,現在不需要去看數組中第幾個參數是我需要使用的了,你完全可以使用:

callMethods(methods, args) {    console.log(methods, args);    let self = this;    let arg = args[0];    switch (methods) {        case 'SayHello':            self.sayHello(arg.message);            break;    }},

這裡還有個問題,就是介面中的方法名是大寫開頭的,而js的規範呢一般都是小寫開頭的,所以在映射方法的時候需要注意下,反正這個大小寫問題有點不是很爽,參數在傳遞的時候倒是直接轉換成首字母小寫,我相信SignalR Core是可以實現的,只是我不知道而已,稍後在研究研究,如果可行,我會更新此篇博文。如果你要在介面中用小寫來定義這個方法,也沒有問題,但我覺得就是不符合規範,習慣不允許我如此粗糙,哈哈。

寫在最後

至於調用的原理,我沒有細看,正好在看源碼的時候,看到了Hub,很疑惑,嘗試了下後才發覺SignalR的牛逼,後來發現其實在SignalR 2.1中引用了這個概念,估計很多人已經在用了,但好像提到的人很少,包括微軟的文檔,這次也是意外發現,趕快記錄下來,希望對您有用。

Asp.Net Core SignalR確實很強大,有興趣的可以去gayhub上去研究下他們的源碼。

相關文章

Alibaba Cloud 10 Year Anniversary

With You, We are Shaping a Digital World, 2009-2019

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。