SingnalR 开发到生产部署闭坑指南

简介: 前天倒腾了一份[SignalR在react/go技术栈的实践], 步骤和思路大部分是外围框架的应用, 今天趁热打铁, 给一个我总结的SignalR避坑指南。

01

SignalR默认要协商传输方式


SignalR 默认要求协商传输方式[1]


不管是.NET客户端还是JavaScript客户端,构建连接时都存在一个默认配置:

SkipNegotiation=fasle,负负得正就等于要求协商,这个默认配置的完整含义是 建立SignalR连接时,客户端要求协商传输方式


对应产生下图:


0484fdb85d93a87112b00e0e90677a9f.png


小技巧如果你确定你的网络环境能稳定的走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请求


f279aa48e4281fc2ca165b9626a66a88.png


故你还需要在使用 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模式,传输成功。


78c72ba4ac6bde2747b985f3d78313f6.png


浏览器开发者工具看不出啥端倪, 使用Fiddler抓包发现 400 状态码


d3b9d605bfffe7eca399c526402aae53.png


网上搜索了一下,可能是生产的nginx不识别websocket标头。在nginx配置里面添加如下配置就可以了。


location / {
     proxy_http_version 1.1; 
     proxy_set_header Upgrade $http_upgrade;                
     proxy_set_header Connection "upgrade";    
}


以上是马甲哥整理的SignalR从开发到部署的闭坑指南


相关文章
|
6月前
|
消息中间件 监控 NoSQL
容器化应用系统上生产的最佳实践
容器化应用系统上生产的最佳实践
|
7天前
|
敏捷开发 数据可视化 数据挖掘
从需求到交付:五种管理方法让研发流程更高效
产品研发团队面临需求多变、任务紧迫等挑战,需要高效的管理方法来提升协作和执行力。本文推荐五种方法:看板管理、MVP最小可行产品、用户故事地图、双钻模型及Scrum框架,帮助团队实现“巧干”。
30 1
从需求到交付:五种管理方法让研发流程更高效
|
6月前
|
数据采集 存储 运维
提升团队工程交付能力,从“看见”工程活动和研发模式开始
本文从统一工程交付的概念模型开始,介绍了如何将应用交付的模式显式地定义出来,并通过工具平台落地。
122603 420
|
4月前
|
监控 数据可视化 调度
ERP系统中的生产计划优化与生产效率提升解析
【7月更文挑战第25天】 ERP系统中的生产计划优化与生产效率提升解析
364 0
|
6月前
|
存储 运维 安全
MES生产管理系统:私有云、公有云与本地化部署的比较分析
企业在选择云计算部署方式时,应根据自身的业务需求、安全要求、成本预算和技术实力进行综合考虑。对于需要高度安全可控和个性化定制的企业,私有云可能是一个更好的选择;对于成本敏感、追求灵活性和快速扩展的企业,公有云可能更具吸引力;而对于对稳定性和安全性要求较高、对外部依赖度较低的企业,本地化部署可能更合适。在实际应用中,企业也可以考虑采用混合云策略,结合私有云、公有云和本地化部署的优势,实现资源的灵活配置和高效利用。
267 0
MES生产管理系统:私有云、公有云与本地化部署的比较分析
|
6月前
|
传感器 监控 供应链
自动化生产线上的应用
自动化生产线广泛应用在汽车、电子、食品和医药等领域,提高生产效率和质量,节约人力成本。其优势包括生产稳定性强、适应恶劣环境、24小时不间断生产及产品一致性高。随着技术进步,未来自动化生产线将更灵活、定制化,人机融合、绿色环保和智能监控将成为趋势。传感器和电动执行器作为关键组件,优化监控和控制,推动生产效率和质量提升,为企业带来更多机遇与挑战。
113 2
|
6月前
|
传感器 监控 数据可视化
万界星空MES安灯管理:优化生产监控的重要工具
MES安灯管理是一种基于物理安灯和数字化管理的生产异常管理工具。它通过物理安灯和数字化系统的结合,实现对生产异常的实时监控和及时反馈,从而帮助企业快速响应和解决生产异常,提高生产效率和产品质量。
196 0
万界星空MES安灯管理:优化生产监控的重要工具
|
Kubernetes 网络安全 数据安全/隐私保护
k3s部署全过程
k3s部署全过程
616 0
k3s部署全过程
|
Kubernetes 网络安全 Docker
生产级K8S基础环境部署-20210917
生产级K8S基础环境部署-20210917
280 0
|
IDE NoSQL Cloud Native
研发与环境的那些事儿
研发与环境的那些事儿
研发与环境的那些事儿
下一篇
无影云桌面