日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SignalR在React/Go技术栈的实践

發布時間:2023/12/4 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SignalR在React/Go技术栈的实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

哼哧哼哧半年,優化改進了一個運維開發web平臺。
本文記錄SignalR在react/golang 技術棧的生產小實踐。

01

背景

有個前后端分離的運維開發web平臺, 后端會間隔5分鐘同步一次數據,現在需要將最新一次同步的時間推送到web前端。

說到[web服務端推送],立馬想到SignalR,(我頭腦中一直有技術體系, 但一直沒實踐過。)

SignalR是微軟推出的實時通信標準框架,內部封裝了 websocket、服務端發送事件、長輪詢, 可以算是實時通信的大殺器,傳送門。

實際編碼就是react寫SignalR客戶端,golang寫SignalR服務端,盲猜有對應的輪子。

02

擼起袖子干

果然, signalr的作者David Fowler實現了node、go版本, 這位老哥是.NET技術棧如雷貫耳的大牛:

但是他的倉庫很久不更了,某德國大佬在此基礎上開了新github倉庫[1]繼續支持。

SignalR的基本交互原理:

(1) signalR提供了一組API, 用于創建從服務端到客戶端的遠程過程調用(RPC),這個調用的具體體現是 :從服務端.NET 代碼調用位于客戶端的javascript 代碼。

(2) signalr提供了管理實例、連接、失連, 分組管控的API。

這里面最關鍵的一個概念是集線器Hub,其實也就是RPC領域常說的客戶端代理。
服務端在baseUrl上建立signalr的監聽地址;
客戶端連接并注冊receive事件;

服務端在適當時候通過hubServer向HubClients發送數據。

go服務端

(1) 添加golang pgk:go get github.com/philippseith/signalr

(2) 定義客戶端集線器hub,這里要實現HubInterface接口的幾個方法, 你還可以為集線器添加一些自定義方法。

package?servicesimport?("github.com/philippseith/signalr"log?"github.com/sirupsen/logrus""time" )type?AppHub?struct{signalr.Hub }func?(h?*AppHub)?OnConnected(connectionID?string)?{//?fmt.Printf("%s?connected\n",?connectionID)log.Infoln(connectionID,"?connected\n"?) }func?(h?*AppHub)?OnDisconnected(connectionID?string)?{log.Infoln(connectionID,"?disconnected\n") }//?客戶端調用的函數,?本例不用 func?(h?*AppHub)?Send(message?string)?{h.Clients().All().Send("receive",?time.Now().Format("2006/01/02?15:04:05")?) }

(3) 初始化集線器, 并在特定地址監聽signalr請求。

這個庫將signalr監聽服務抽象為獨立的hubServer

shub?:=?services.AppHub{}sHubSrv,err:=?signalr.NewServer(context.TODO(),signalr.UseHub(&shub),?//?這是單例hubsignalr.KeepAliveInterval(2*time.Second),signalr.Logger(kitlog.NewLogfmtLogger(os.Stderr),?true))sHubSrv.MapHTTP(mux,?"/realtime")

(4) 利用sHubServer在合適業務代碼位置向web客戶端推送數據。

if?clis:=?s.sHubServer.HubClients();?clis!=?nil?{c:=?clis.All()if??c!=?nil?{c.Send("receive",ts.Format("2006/01/02?15:04:05"))}}

注意:上面的receive方法是后面react客戶端需要監聽的JavaScript事件名。

react客戶端

前端菜雞,跟著官方示例琢磨了好幾天。

(1) 添加@microsoft/signalr 包

(2) 在組件掛載事件componentDidMount初始化signalr連接

實際也就是向服務端baseUrl建立HubConnection,注冊receive事件,等待服務端推送。

import?React?from?'react'; import?{JsonHubProtocol,HubConnectionState,HubConnectionBuilder,HttpTransportType,LogLevel, }?from?'@microsoft/signalr';class?Clock?extends?React.Component?{constructor(props)?{super(props);this.state?=?{message:'',hubConnection:?null,};}componentDidMount()?{const?connection?=?new?HubConnectionBuilder().withUrl(process.env.REACT_APP_APIBASEURL+"realtime",?{}).withAutomaticReconnect().withHubProtocol(new?JsonHubProtocol()).configureLogging(LogLevel.Information).build();//?Note:?to?keep?the?connection?open?the?serverTimeout?should?be//?larger?than?the?KeepAlive?value?that?is?set?on?the?server//?keepAliveIntervalInMilliseconds?default?is?15000?and?we?are?using?default//?serverTimeoutInMilliseconds?default?is?30000?and?we?are?using?60000?set?belowconnection.serverTimeoutInMilliseconds?=?60000;//?re-establish?the?connection?if?connection?droppedconnection.onclose(error?=>?{console.assert(connection.state?===?HubConnectionState.Disconnected);console.log('Connection?closed?due?to?error.?Try?refreshing?this?page?to?restart?the?connection',?error);});connection.onreconnecting(error?=>?{console.assert(connection.state?===?HubConnectionState.Reconnecting);console.log('Connection?lost?due?to?error.?Reconnecting.',?error);});connection.onreconnected(connectionId?=>?{console.assert(connection.state?===?HubConnectionState.Connected);console.log('Connection?reestablished.?Connected?with?connectionId',?connectionId);});this.setState({?hubConnection:?connection})this.startSignalRConnection(connection).then(()=>?{if(connection.state?===?HubConnectionState.Connected)?{connection.invoke('RequestSyncTime').then(val?=>?{console.log("Signalr?get?data?first?time:",val);this.setState({?message:val?})})}})?;connection.on('receive',?res?=>?{console.log("SignalR?get?hot?res:",?res)this.setState({message:res});});}startSignalRConnection?=?async?connection?=>?{try?{await?connection.start();console.assert(connection.state?===?HubConnectionState.Connected);console.log('SignalR?connection?established');}?catch?(err)?{console.assert(connection.state?===?HubConnectionState.Disconnected);console.error('SignalR?Connection?Error:?',?err);setTimeout(()?=>?this.startSignalRConnection(connection),?5000);}};render()?{return?(<div?style={{width:?'300px',float:'left',marginLeft:'10px'}}?><h4>最新同步完成時間:?{this.state.message}??</h4></div>);}}export??default??Clock;

(3) 將該react組件插入到web前端頁面

03

效果分析

最后的效果如圖:

效果分析:

(1) web客戶端與服務器協商 傳輸方式http://localhost:9598/realtime/negotiate?negotiateVersion=1,
返回可用的傳輸方式和連接標識ConnectionId。

{"connectionId":?"hkSNQT-pGpZ9E6tuMY9rRw==","availableTransports":?[{"transport":?"WebSockets","transferFormats":?["Text",?"Binary"]},?{"transport":?"ServerSentEvents","transferFormats":?["Text"]}] }

(2) web客戶端利用上面的ConnectionId向特定的服務器地址/realtime連接,建立傳輸通道,默認優先websocket。

以上網絡交互,大部分會通過SignalR框架自動完成。

源碼:Github Demo[2]

引用鏈接

[1]?Github倉庫:?https://github.com/philippseith/signalr
[2]?Github Demo:?https://github.com/zaozaoniao/SignalR-apply-to-react-and-golang

●實時通信技術大亂斗

●.NET WebSocket 核心原理初體驗

●.NET gRPC核心功能初體驗

●大前端快閃四:這次使用一個舒服的姿勢插入HttpClient攔截器

●大前端快閃三:多環境靈活配置react

●大前端快閃二:react開發模式 一鍵啟動多個服務

●大前端快閃:package.json文件知多少?

“贊”“在看”

體現態度很有必要!

總結

以上是生活随笔為你收集整理的SignalR在React/Go技术栈的实践的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。