SignalR在React/Go技术栈的实践

a986ae12c67b197ca4c26d3b61cc8ecd.gif

哼哧哼哧半年,优化改进了一个运维开发web平台。
本文记录SignalR在react/golang 技术栈的生产小实践。

01

背景

有个前后端分离的运维开发web平台, 后端会间隔5分钟同步一次数据,现在需要将最新一次同步的时间推送到web前端。

说到[web服务端推送],立马想到SignalR,(我头脑中一直有技术体系, 但一直没实践过。)

SignalR是微软推出的实时通信标准框架,内部封装了 websocket、服务端发送事件、长轮询, 可以算是实时通信的大杀器,传送门。

实际编码就是react写SignalR客户端,golang写SignalR服务端,盲猜有对应的轮子。

02

撸起袖子干

果然, signalr的作者David Fowler实现了node、go版本, 这位老哥是.NET技术栈如雷贯耳的大牛:

89d7508992b7a122861ea5f3109b2e2b.png

但是他的仓库很久不更了,某德国大佬在此基础上开了新github仓库[1]继续支持。

SignalR的基本交互原理:

(1) signalR提供了一组API, 用于创建从服务端到客户端的远程过程调用(RPC),这个调用的具体体现是 :从服务端.NET 代码调用位于客户端的javascript 代码。

(2) signalr提供了管理实例、连接、失连, 分组管控的API。

e635ce69a7cc82c750aa6db65b249f92.png

这里面最关键的一个概念是集线器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

效果分析

最后的效果如图:

56835a799c443736c440708bd8ff9d9b.gif

效果分析:

(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。

5d87a7fb7e8309ebdcf93c0527220811.png

以上网络交互,大部分会通过SignalR框架自动完成。

源码:Github Demo[2]

e9249ba8b2a79d2d06a7d340f987d84d.png

引用链接

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

2f9bcdc59a3ca88af6687eb50b763b40.gif

●实时通信技术大乱斗

●.NET WebSocket 核心原理初体验

●.NET gRPC核心功能初体验

●大前端快闪四:这次使用一个舒服的姿势插入HttpClient拦截器

●大前端快闪三:多环境灵活配置react

●大前端快闪二:react开发模式 一键启动多个服务

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

“赞”c1804ce877a55f90662583b326de6a47.gif“在看”15e6ee14eae97e1c222dca6d3a40c059.gif

体现态度很有必要!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/296739.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

16张扎心漫画,戳中女生私密日常,每一幕都很真实

全世界只有3.14 % 的人关注了爆炸吧知识比利时的插画师Planet Prudence&#xff0c;画了很多女生的真实日常&#xff0c;每一幕都很戳心&#xff0c;一起来看看吧。别人的痘痘一长就是一个&#xff0c;我一长就是一片。买买买的时候爽得要命&#xff0c;要穿的时候总觉得自己没…

Magicodes.IE 2.5.6.2发布

2.5.6.22021.10.13支持自定义列字体颜色&#xff0c;具体见PR#342&#xff0c;感谢xiangxiren修复日期格式化的问题&#xff0c;具体见PR#344&#xff0c;感谢ccccccmd2.5.6.12021.10.06修复 #337&#xff0c;bool?类型导出的映射问题2.5.6.02021.10.05合并Magicodes.EPPlus到…

一个让我很不爽的外包项目——奔驰Smart2015新官网

七月份的下半个月&#xff0c;有幸做了奔驰 Smart 2015年新官网&#xff0c;包括手机端和PC端的宣传页&#xff0c;地址&#xff1a; PC端手机端这里&#xff0c;为了证明这个是一个事实&#xff0c;我还特意的留存了两张截图&#xff1a; 这里只想说明这么几个问题&#xff1a…

为什么饮料瓶大都是圆的,牛奶盒却是方的?原因你想不到

全世界只有3.14 % 的人关注了爆炸吧知识每日看着电视玩着手机再喝着饮料那是相当美好但是喝了这么久的饮料你有没有想过一个问题为什么饮料瓶一般都是圆的&#xff1f;而牛奶盒却是方的&#xff1f;图片来源网络有的人可能会说饮料瓶要拿在手上当然是圆的舒服啊拿着一个方形的饮…

IIS相关问题及解决方案

1、问题&#xff1a;HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配 可能原因&#xff1a;在自己使用IIS发布网站之后&#xff0c;自己所使用的当前账户的密码改变了。 解决方法&#xff1a;将用户才密码改回来即可.... 2. 转载于:https://www.…

博客园html源码编辑出错,博客园小技巧

作者&#xff1a;Vamei 出处&#xff1a;http://www.cnblogs.com/vamei 欢迎转载&#xff0c;也请保留这段声明。谢谢&#xff01;在博客园写博的半年中&#xff0c;我有时会纠结于一些诸如写作格式和显示效果之类的小问题。我想任何一个热衷于在这里写博客的人都可能会遇到类似…

使用零代码平台构建应用,应该怎样转变思路?

最近两年&#xff0c;越来越多的各类零代码产品在市场上出现&#xff0c;与此同时&#xff0c;企业的数字化转型的速度也越来越快&#xff0c;零代码产品已然成为了帮助企业数字化转型的利器。技术也在不断地演进&#xff0c;其核心目的就是让开发人员能够更专注于业务逻辑&…

看了这几幅图,感觉自己物理白学了!

全世界只有3.14 % 的人关注了爆炸吧知识看完觉得自己即将成为21世纪最伟大的科学家&#xff01;据说&#xff0c;物理老师看到这几幅图&#xff0c;会说不出话来……不信&#xff0c;转给你们老师看看&#xff0c;嘿嘿嘿……来源&#xff1a;物理知识大全

在Web应用中使用localforage存储离线数据

在现代Web应用中&#xff0c;我们经常会需要在本地存储一些数据&#xff0c;一方面记住用户的一些状态&#xff0c;或个性化设置&#xff0c;尤其是可以缓存一些常用&#xff08;甚至全部&#xff09;的数据&#xff0c;实现更加强大和丰富的本地交互体验。传统上说&#xff0c…

出差一定要给孩子带特产

1 这就是热恋期管不住自己的情侣▼2 热恋期过了...▼3 这该夸你腰细呢&#xff1f;还是脸大呢&#xff1f;▼4 听起来...不是挺好的吗▼5 由于新冠病毒&#xff0c;美国GCW选手都保持着一定距离改用原力来进行比赛▼6 她们太菜了你跟她们好以后肯定疯狂掉分▼7 出差一定…

计算机用户名密码策略,设置域用户帐户密码策略

从安全和易用考虑&#xff0c;普通域用户的帐户策略必须满足一下要求&#xff1a;u 密码长度至少3位u 最长使用期限60天u 密码必须符合复杂性要求u 密码最短使用0天u 帐户锁定阀值7次u 帐户锁定时间30分钟u 复位帐户锁定计数器30分钟任务:u 使用默认域策略设置域用户帐户策略u …

优秀的硕博士们,他们的朋友圈都有什么特点?

全世界只有3.14 % 的人关注了爆炸吧知识很多同学都会有这种感觉&#xff0c;读了硕士博士后&#xff0c;兴趣会突然间发生很大变化&#xff0c;发朋友圈也会不一样了。例如&#xff0c;合格的学术研究者&#xff0c;要快速、全面的获取各种最新文献和学界动态&#xff1b;还要持…

未来教育计算机二级Excel解析,Excel操作小技巧,助你学好计算机二级office!

原标题&#xff1a;Excel操作小技巧&#xff0c;助你学好计算机二级office&#xff01;Office考试中最难的是什么&#xff1f;当然是Excel函数啊&#xff01;小编辛苦整理了excel10大懒人技巧&#xff0c;让你考试速提分&#xff01;还不赶紧收藏起来一、填充合并单元格在工作表…

当你女朋友向你索吻的时候。。

1 当你女朋友向你索吻的时候。。2 可把我厉害坏了&#xff0c;叉会腰&#xff01;3 这脸大的&#xff0c;超想捏4 网友制作的饭团&#xff0c;拍个照都怕打扰他的美梦5 有些话我嘴上不说&#xff0c;但希望你心里有数&#xff01;6 这是一道很神奇的计算题。。你点的每个赞&…

要来吗,不错的WPF技术交流群!(大批干货今日自取)

欢迎加入我的编程技术交流群今日分享&#xff1a;1 《WPF-微软官方文档》2 《WPF客户端应用系统开发实战》全集3 《2021秋招WPF高频面试题-附答案》欢迎加入我的编程技术交流群MVP答疑解惑超多技术干货免费获取优质岗位和技术兼职内推和数百.NET/WPF 开发者一起进阶众多资料今…

用计算机配置打印机IP,网络打印机怎么设置ip(手把手教你设置打印机IP地址)...

如何设置打印机IP地址&#xff0c;是一个长期以来困好多小伙伴的一个问题&#xff0c;那今天我们就以 HP Laserjet Pro 100 MFP M128系列打印机为例&#xff0c;为大家介绍一下打印机IP地址的设置方法~步骤一&#xff1a;打印配置报告查看有效IP地址M128fp&#xff0c;M128fna …

河流为什么是弯曲的?

全世界只有3.14 % 的人关注了爆炸吧知识我们看到的河流&#xff0c;特别是在平原上的河流&#xff0c;总是弯弯曲曲&#xff0c;很少有笔直的河道。这是为什么呢&#xff1f;这得从力学上做一点解释。图1 弯弯曲曲的河流首先我们来关注一个流体力学中的二次流现象。取一口宽底的…

poj--2019 Cornfields 2维RMQ

题目大意&#xff1a; 给定一个 N*N 的数组 求以&#xff08;x1&#xff0c; y1&#xff09; 为左上角 &#xff08;x1 b -1 &#xff0c;y1 b -1)为右下角 这个b*b的范围内最大值减最小值 看到最大值最小值当然想到RMQ啦 View Code //Accepted 27392K 594MS C …

学生渐进片add如何给_渐进镜片的说明与镜架选择

近年来&#xff0c;许多眼镜店都进行了渐进多焦点镜片(下面简称&#xff1a;渐进镜片)的推广与应用&#xff0c;产品也越来越普及&#xff0c;但由于很多眼镜店并没有对从业人员进行系统培训&#xff0c;同时对渐进镜片的了解又甚少&#xff0c;在一些注意事项上经验不足&#…

html5 svg组态图,绘制SVG内容到Canvas的HTML5应用

SVG与Canvas是HTML5上绘制图形应用的两种完全不同模式的技术&#xff0c;两种绘制图形方式各有优缺点&#xff0c;但两者并非水火不容&#xff0c;尤其是SVG内容可直接绘制在Canvas上的功能&#xff0c;使得两者可以完美的融合在一起&#xff0c;让Canvas可享用到现有丰富的SVG…