網(wǎng)站首頁 編程語言 正文
何為實時
先從理論上解釋一下兩者的區(qū)別。
大多數(shù)傳統(tǒng)的web應(yīng)用是這樣的:客戶端發(fā)起http請求到服務(wù)端,服務(wù)端返回對應(yīng)的結(jié)果。像這樣:
也就是說,傳統(tǒng)的web應(yīng)用都是客戶端主動發(fā)起請求到服務(wù)端。
那么實時web應(yīng)用呢?它不需要主動發(fā)起請求,服務(wù)端可以主動推送信息到客戶端。
舉栗子的話,實時聊天工具、web游戲等都可以算是實時應(yīng)用。
什么是SignalR
如果想做一個實時應(yīng)用,最好用web socket。很早以前我也寫過web socket的實現(xiàn)方式,但不夠全面,這里再補上一篇。
來說說signalR,它是一款開源的實時框架,可以使用三種方式實現(xiàn)通信(long polling、server sent events、web socket)。它很好的整合了底層技術(shù),讓我們可以不用關(guān)注底層技術(shù)實現(xiàn)而把精力聚焦在業(yè)務(wù)實現(xiàn)上。一個完整的signalR包括客戶端和服務(wù)端,服務(wù)端支持net core/net framework,還支持大部分客戶端,比如瀏覽器和桌面應(yīng)用。
回落機制
為了兼容不同瀏覽器(客戶端)和服務(wù)端,signalR采用了回落機制,使得它可以根據(jù)情況協(xié)商使用不同的底層傳輸方式。假如瀏覽器不支持web socket,就自動降級使用sse,再不行就long polling。當然,也可以禁用這種機制,指定其中一種。
三種通信方式
long polling(長輪詢)
長輪詢是客戶端發(fā)起請求到服務(wù)端,服務(wù)器有數(shù)據(jù)就會直接返回。如果沒有數(shù)據(jù)就保持連接并且等待,一直到有新的數(shù)據(jù)返回。如果請求保持到一段時間仍然沒有返回,這時候就會超時,然后客戶端再次發(fā)起請求。
這種方式優(yōu)點就是簡單,缺點就是資源消耗太多,基本是不考慮的。
server sent events(sse)
如果使用了sse,服務(wù)器就擁有了向客戶端推送的能力,這些信息和流信息差不多,期間會保持連接。
這種方式優(yōu)點還是簡單,也支持自動重連,綜合來講比long polling好用。缺點也很明顯,不支持舊的瀏覽器不說,還只能發(fā)送本文信息,而且瀏覽器對sse還有連接數(shù)量的限制(6個)。
web socket
web socket允許客戶端和服務(wù)端同時向?qū)Ψ桨l(fā)送消息(也就是雙工通信),而且不限制信息類型。雖然瀏覽器同樣有連接數(shù)量限制(可能是50個),但比sse強得多。理論上最優(yōu)先使用。
進入正題
開始之前,還需要了解RPC和Hub的概念。
- RPC:全稱Remote Procedure Call,字面意思遠程服務(wù)調(diào)用,可以像調(diào)用本地方法一樣調(diào)用遠程服務(wù)。前端可以調(diào)用后端方法,后端也可以調(diào)用前端方法。
- Hub:基于RPC,接受從客戶端發(fā)過來的消息,也同時負責把服務(wù)端的消息發(fā)送給客戶端。客戶端可以調(diào)用Hub里面的方法,服務(wù)端可以通過Hub調(diào)用客戶端里面的方法。
好了,概念已經(jīng)理解清楚了,接下來上代碼。
在項目里新增Hub類:
using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace SignalRDemo.Server { public class SignalRHub : Hub { /// <summary> /// 客戶連接成功時觸發(fā) /// </summary> /// <returns></returns> public override async Task OnConnectedAsync() { var cid = Context.ConnectionId; //根據(jù)id獲取指定客戶端 var client = Clients.Client(cid); //向指定用戶發(fā)送消息 await client.SendAsync("Self", cid); //像所有用戶發(fā)送消息 await Clients.All.SendAsync("AddMsg", $"{cid}加入了聊天室"); } } }
為了讓外部可以訪問,我們還需要一個控制器。在控制器里聲明隨便建一個:
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using SignalRDemo.Server; using System.Threading.Tasks; namespace SignalRDemo.Controllers { public class HomeController : Controller { private readonly IHubContext<SignalRHub> _countHub; public HomeController(IHubContext<SignalRHub> countHub) { _countHub = countHub; } /// <summary> /// 發(fā)送信息 /// </summary> /// <param name="msg"></param> /// <param name="id"></param> /// <returns></returns> public async Task Send(string msg, string id) { await _countHub.Clients.All.SendAsync("AddMsg", $"{id}:{msg}"); } } }
再然后進入StartUp設(shè)置端點:
endpoints.MapHub<SignalRHub>("/hub");
完成以后,配置signalr客戶端:
setupConn = () => { conn = new signalR.HubConnectionBuilder() .withUrl("/hub") .build(); conn.on("AddMsg", (obj) => { $('#msgPanel').append(`<p>${obj}</p>`); }); conn.on("Finished", () => { conn.stop(); $('#msgPanel').text('log out!'); }); conn.on("Self", (obj) => { $('#userId').text(obj); }); conn.start() .catch(err => console.log(err)); }
要注意withUrl里面的路徑就是之前設(shè)置好的端點。
運行效果:
Hub還支持組操作,比如:
//將用戶添加到A組 await Groups.AddToGroupAsync(Context.ConnectionId, "GroupA"); //將用戶踢出A組 await Groups.RemoveFromGroupAsync(Context.ConnectionId, "GroupA"); //向A組所有成員廣播消息 await Clients.Group("GroupA").SendAsync("AddMsg", "群組消息");
更多操作請參考官方文檔。
本文演示demo的源碼見git,地址:https://gitee.com/muchengqingxin/SignalRDemo.git
原文鏈接:https://www.cnblogs.com/muchengqingxin/p/13195229.html
相關(guān)推薦
- 2023-03-19 Redis+Hbase+RocketMQ?實際使用問題案例講解_Redis
- 2022-04-08 go實現(xiàn)圖片拼接與文字書寫的方法實例_Golang
- 2022-06-01 Go中的gRPC入門教程詳解_Golang
- 2023-03-03 詳解C++?STL模擬實現(xiàn)forward_list_C 語言
- 2022-10-22 react實現(xiàn)Modal彈窗效果_React
- 2022-06-22 C語言詳解判斷相同樹案例分析_C 語言
- 2023-02-05 通過示例學習python中os模塊的使用_python
- 2022-05-14 實現(xiàn)AJAX異步調(diào)用和局部刷新的基本步驟_AJAX相關(guān)
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支