SingnalR 开发到生产部署闭坑指南
前天倒騰了一份[SignalR在react/go技術棧的實踐
01
SignalR默認要協商傳輸方式
SignalR 默認要求協商傳輸方式[1]
不管是.NET客戶端還是JavaScript客戶端,構建連接時都存在一個默認配置:SkipNegotiation=fasle,負負得正就等于要求協商,這個默認配置的完整含義是?建立SignalR連接時,客戶端要求協商傳輸方式。
對應產生下圖:
小技巧(嬉笑臉):如果你確定你的網絡環境能穩定的走websocket傳輸, 為了快速建立實時通信,可跳過協商請求(設置SkipNegotiation=true), 畢竟每次刷新頁面,react組價都會重新加載,重新協商再傳輸 費時費力。const?connection?=?new?HubConnectionBuilder().withUrl(process.env.REACT_APP_APIBASEURL+"realtime",?{skipNegotiation:?true,??transport:?HttpTransportType.WebSockets}).withAutomaticReconnect().withHubProtocol(new?JsonHubProtocol()).configureLogging(LogLevel.Information).build();注意:SkipNegotiation=true,僅限于客戶端的傳輸方式指定為 websocket, 其他方式均會報錯。
02
SignalR傳輸協商是fetch請求
? ? ?跟ajax一樣,fetch請求[2]也是瀏覽器腳本的一種,所以很明顯也會涉及跨域,標準的CORS方案依然對其有效。
http://localhost:9598/realtime/negotiate?negotiateVersion=1
Post請求
有自定義的請求頭 X-Requested-With, X-Signalr-User-Agent
很明顯,這又會觸發預檢Option請求
故你還需要在使用 CORS Middleware時允許這幾個自定義請求頭。
//?下面是Go?github.com/rs/cors?package?支持CORS的代碼c?:=?cors.New(cors.Options{//?AllowedOrigins:???[]string{"http://localhost:3000","http://rosenbridge.17usoft.com"},AllowOriginFunc:?func(origin?string)?bool?{return?true},AllowedMethods:???[]string{"POST",?"GET",?"OPTIONS",?"PUT",?"DELETE"},??//?下面要加上signalr傳輸協商要用到的自定義請求頭AllowedHeaders:???[]string{"Content-Type",?"x-requested-with",?"x-signalr-user-agent"},AllowCredentials:?true,Debug:????????????cfg.Log.Debug,})03
WebSocket請求也有同源限制
ws://localhost:9598/realtime?id=aoSD_WZhqbRfPyXVTYsHig==
WebSocket也有同源限制[3]? (無奈臉),但是標準的CORS對其無效,因為CORS解決是HTTP腳本請求的跨域問題,WebSocket說到底不算http協議。
瀏覽器依舊會為我們攜帶Origin標頭,所以服務端需要驗證這些標頭,確保只允許來自預期來源的WebSocket。
//?以下是.NET?Core?針對websocket同源限制做出的跨域配置var?webSocketOptions?=?new?WebSocketOptions() {KeepAliveInterval?=?TimeSpan.FromSeconds(120), }; webSocketOptions.AllowedOrigins.Add("https://client.com"); webSocketOptions.AllowedOrigins.Add("https://www.client.com");app.UseWebSockets(webSocketOptions);btw, 我使用的GO SignalR庫不支持WebSocket跨域, 我提了一個PR[4], 已經成功合并,(興奮臉),這是我首次向開源項目提PR且獲得通過的項目。
04
部署生產,需要nginx支持
按照默認配置,一般會先協商,再使用websocket傳輸。
部署到生產之后,協商后優先使用WebSocket模式, 但是傳輸失敗了, 自動切換為服務器發送事件SSE模式,傳輸成功。
瀏覽器開發者工具看不出啥端倪, 使用Fiddler抓包發現 400 狀態碼
網上搜索了一下,可能是生產的nginx不識別websocket標頭。在nginx配置里面添加如下配置就可以了。
location?/?{proxy_http_version?1.1;?proxy_set_header?Upgrade?$http_upgrade;????????????????proxy_set_header?Connection?"upgrade";???? }以上是馬甲哥整理的SignalR從開發到部署的閉坑指南,因為微信公眾號內容發布后不方便重新編輯,后續有更多閉坑技能,會同步到大家喜聞樂見的博客園馬甲哥[5]。
還沒完, 因為本文是零散的閉坑指南, 文中點出的坑位其實都有相關技能點,感興趣的童靴可以認真閱讀下面給出的相關推薦(真誠臉)
●實時通信技術大亂斗
●.NET WebSocket 核心原理初體驗
●.NET gRPC核心功能初體驗
●?SignalR在React/Go技術棧的實踐
●?對CORS OPTIONS預檢請求的一些思考
●?程序員應對瀏覽器同源策略的姿勢
引用鏈接
[1]?SignalR 默認先協商:?https://docs.microsoft.com/en-us/aspnet/core/signalr/configuration?view=aspnetcore-5.0&tabs=dotnet
[2]?fetch請求:?https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
[3]?WebSocket也有同源限制:?https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/websockets?view=aspnetcore-5.0
[4]?PR:?https://github.com/philippseith/signalr/pull/75
[5]?博客園馬甲哥:?https://www.cnblogs.com/JulianHuang/p/15434137.html
快完了,號外號外:
本文內容和制圖均為原創,文章永久更新地址請參閱左下角原文,如對您有所幫助,請一鍵三連,激濁揚清,方便的話置一個星標 ~。。~。
關注本號,后臺回復【pdf】,送你號主征戰多年的經典技術PDF:大前端、.net、Go、云原生、數據庫,童嫂無欺,回復【碼甲哥】,加我好友。?
關注本公眾號的5000+筒靴們應該都知道,本號一直不遺余力的輸出原創技術、職場心得,內容說不上什么耳目一新、醍醐灌頂,但號主的技能點一直在進化,本次建立了一個[碼甲哥高質量交流群],希望能和童鞋面對面成長(真誠臉)。
總結
以上是生活随笔為你收集整理的SingnalR 开发到生产部署闭坑指南的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 50个Android应用!Win11支持
- 下一篇: “快准顺”而不是“信达雅”