既然項目中用到了,那就搞搞清楚,搞不懂就死 : >
前置内容:
長輪詢問題在ABP中的解決方案,SignalR_董廠長的部落格-CSDN部落格
“SingalR是對webSocekt的封裝” ,這句話是片面的。
因為:
SignalR支援多種伺服器推送方式:Websocket、Server-Sent Events、長輪詢。預設按順序嘗試。
為什麼支援多種?因為有些浏覽器不支援webSocekt。
websocket和HTTP是不同的協定,為什麼能用同一個端口。
通常 HTTP 是在 TCP 協定之上實作的。
- 如果 x 是基于 UDP 的,則 x HTTP 服務可以部署到“同一個”端口,不過這時的端口已沒有比較的意義,因為 TCP UDP 有各自單獨的協定棧,端口互不相幹
- 如果 x 也是基于 TCP 的,則可以把 x HTTP 服務部署到不同位址(多個網卡多個 ip,或者 0.0.0.0 和本地 ip 上)的相同端口下,不過對于遠端使用者來說沒什麼意義
- x 實作使用 HTTP 協定的握手機制,由 HTTP 服務完成握手并交出 socket 控制權
協定協商的問題
1、叢集中協定協商的問題:“協商”請求被伺服器A處理,而接下來的WebSocket請求卻被伺服器B處理。
2、解決方法:粘性會話和禁用協商。
3、 “粘性會話”(Sticky Session):把來自同一個用戶端的請求都轉發給同一台伺服器上。
交給負載均衡伺服器。
缺點:因為共享公網IP等造成請求無法被平均的配置設定到伺服器叢集;擴容的自适應性不強。
4、“禁用協商”:直接向伺服器發出WebSocket請求。WebSocket連接配接一旦建立後,在用戶端和伺服器端直接就建立了持續的網絡連接配接通道,在這個WebSocket連接配接中的後續往返WebSocket通信都是由同一台伺服器來處理。缺點:無法降級到“伺服器發送事件”或“長輪詢”,不過不是大問題。
禁用協定協商的方式
skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets };
connection = new signalR.HubConnectionBuilder()
.withUrl('https://localhost:7047/Hubs/ChatRoomHub', options)
.withAutomaticReconnect().build();
分布式部署會遇到什麼問題?
1、四個用戶端被連接配接到不同的兩個伺服器上,會出現,群發消息,可能隻有c1和c2知道
2、解決方案:所有伺服器連接配接到同一個消息中間件。前提條件:啟用粘性會話,或者跳過協商
3、官方方案:Redis backplane。
1)NuGet:Microsoft.AspNetCore.SignalR.StackExchangeRedis
2)builder.Services.AddSignalR().AddStackExchangeRedis("127.0.0.1", options => {
options.Configuration.ChannelPrefix = "Test1_";
builder.Services.AddSignalR().AddStackExchangeRedis("127.0.0.1", options => { options.Configuration.ChannelPrefix = "Test1_";
其他更多進階功能:
Part5-20:外部向SignalR的Hub發送消息_哔哩哔哩_bilibiliPart5-20:外部向SignalR的Hub發送消息是.NET 6教程,.Net Core 2022視訊教程,楊中科主講的第163集視訊,該合集共計195集,視訊收藏或關注UP主,及時了解更多相關視訊内容。
https://www.bilibili.com/video/BV1pK41137He?p=163&vd_source=15d3bbce5ead922293cbb9978ffc74a2
});
const options = {