Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参
繼續(xù)學(xué)習(xí)
最近一直在使用Asp.Net Core SignalR(下面成SignalR Core)為小程序提供websocket支持,前端時(shí)間也發(fā)了一個(gè)學(xué)習(xí)筆記,在使用過程中稍微看了下它的源碼,不得不說微軟現(xiàn)在真的強(qiáng)大,很多事情都幫你考慮到了,比如使用Redis,使用Redis后,你的websocket就支持橫向擴(kuò)展了,使用的方式也特別簡單,只需要在services.AddSignalR的后面再加上:
.AddRedis(options => {options.Configuration.ConnectTimeout = 30;options.Configuration.EndPoints.Add("redis ip"); })SignalR Core利用了Redis的發(fā)布訂閱功能,就實(shí)現(xiàn)了橫向擴(kuò)展,再也不用擔(dān)心一臺ws服務(wù)器不夠用了.
今天要說的并不是SignalR Core的負(fù)載均衡方式,而是如何優(yōu)雅的調(diào)用前端方法。大家都知道SignalR Core除了可以建立websocket連接,還能雙向調(diào)用,服務(wù)器調(diào)用客戶端方法,客戶端也能調(diào)用服務(wù)器的方法。
原始調(diào)用
我們看下如何調(diào)用客戶端方法:
public class ChatHub : Hub{ ? ?//服務(wù)端方法public async Task SendMessage(string user, string message) ? ?{ ? ? ? ?//ReceiveMessage 為客戶端方法,讓所有客戶端調(diào)用這個(gè)方法await Clients.All.SendAsync("sayHello", user, message);} }還是ChatHub~~~~~
我們可以看到在這里我們調(diào)用了客戶端的sayHello,并傳遞了兩個(gè)字符串參數(shù)user,message,是不是覺得丑陋,說實(shí)在的真心看不下去哈。而且不變維護(hù),相當(dāng)于你要把方法名硬編碼,傳遞多少個(gè)參數(shù)也沒有個(gè)準(zhǔn),沒有好的文檔后期很難維護(hù)。好在微軟已經(jīng)為我們考慮到了這個(gè)情況,我們可以把客戶端的方法用接口的方法定義了!!!對!沒錯,用接口的方式定義客戶端的方法!!
優(yōu)雅調(diào)用
使用的方式也超級簡單,我們先定義一個(gè)客戶端的接口:
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 為客戶端方法,讓所有客戶端調(diào)用這個(gè)方法//await Clients.All.SendAsync("sayHello", user, message);} }注釋掉的是我之前的方式,SayHello是客戶端的方法,會通過websocket傳遞到前端,下圖為我用小程序通訊產(chǎn)生的結(jié)果:
是不是SoEasy??我覺得還不算完,我們參數(shù)目前是按照數(shù)組的方式傳遞的,如果有限定的參數(shù)名就完美了,我們改造下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}"); }
在運(yùn)行下我們的小程序:
LooK,方法名沒有改變,但是我們返回的參數(shù)成了一個(gè)對象,如果看過我之前那篇博文的話,應(yīng)該記得在前端的時(shí)候,我需要做一個(gè)映射,來調(diào)用前端的方法,在映射中,我參數(shù)使用的是數(shù)組進(jìn)行傳遞的,現(xiàn)在不需要去看數(shù)組中第幾個(gè)參數(shù)是我需要使用的了,你完全可以使用:
? ?console.log(methods, args); ?
? ?let self = this; ?
? ?let arg = args[0]; ? ?
? ?switch (methods) { ? ? ?
? ? ?case 'SayHello':self.sayHello(arg.message); ? ? ?
? ? ? ? ? ?break;} },
這里還有個(gè)問題,就是接口中的方法名是大寫開頭的,而js的規(guī)范呢一般都是小寫開頭的,所以在映射方法的時(shí)候需要注意下,反正這個(gè)大小寫問題有點(diǎn)不是很爽,參數(shù)在傳遞的時(shí)候倒是直接轉(zhuǎn)換成首字母小寫,我相信SignalR Core是可以實(shí)現(xiàn)的,只是我不知道而已,稍后在研究研究,如果可行,我會更新此篇博文。如果你要在接口中用小寫來定義這個(gè)方法,也沒有問題,但我覺得就是不符合規(guī)范,習(xí)慣不允許我如此粗糙,哈哈。
寫在最后
至于調(diào)用的原理,我沒有細(xì)看,正好在看源碼的時(shí)候,看到了Hub,很疑惑,嘗試了下后才發(fā)覺SignalR的牛逼,后來發(fā)現(xiàn)其實(shí)在SignalR 2.1中引用了這個(gè)概念,估計(jì)很多人已經(jīng)在用了,但好像提到的人很少,包括微軟的文檔,這次也是意外發(fā)現(xiàn),趕快記錄下來,希望對您有用。
Asp.Net Core SignalR確實(shí)很強(qiáng)大,有興趣的可以去gayhub上去研究下他們的源碼。
原文地址:https://www.cnblogs.com/inday/p/signalR-core-grace-call-client-methods.html
.NET社區(qū)新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的Asp.Net Core SignalR 用泛型Hub优雅的调用前端方法及传参的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实战中的asp.net core结合Co
- 下一篇: 使用.NET Core 2.1的Azur