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从开发到部署的闭坑指南


相关文章
uniapp Vue3 日历 可签到 跳转
uniapp Vue3 日历 可签到 跳转
149 0
|
10月前
|
负载均衡 网络协议 算法
|
6月前
|
机器学习/深度学习 数据可视化
Visual-RFT:基于强化学习的视觉语言模型微调技术研究
Visual-RFT 是一种创新的视觉语言模型微调技术,结合基于规则的可验证奖励与强化学习,克服了传统监督微调在数据稀缺场景下的局限。它通过渐进式推理和多样化响应生成,优化模型在对象检测、图像分类等任务中的表现,尤其适用于少样本学习。该方法采用组相对策略优化(GRPO)进行参数更新,简化了强化学习流程,同时保持高效性。实验结果表明,Visual-RFT 在细粒度分类和推理定位等任务中显著优于传统方法,展示了其在实际应用中的巨大潜力。
275 1
Visual-RFT:基于强化学习的视觉语言模型微调技术研究
【VMware】WIN11/WIN11家庭版禁用Device Guard
【VMware】WIN11/WIN11家庭版禁用Device Guard
|
7月前
|
机器学习/深度学习 计算机视觉
YOLOv11改进策略【注意力机制篇】| ICLR2023 高效计算与全局局部信息融合的 Sea_Attention 模块(含C2PSA二次创新)
YOLOv11改进策略【注意力机制篇】| ICLR2023 高效计算与全局局部信息融合的 Sea_Attention 模块(含C2PSA二次创新)
423 2
YOLOv11改进策略【注意力机制篇】| ICLR2023 高效计算与全局局部信息融合的 Sea_Attention 模块(含C2PSA二次创新)
|
存储
LangChain 构建问题之MetaGPT 对复杂任务的处理如何解决
LangChain 构建问题之MetaGPT 对复杂任务的处理如何解决
190 0
|
12月前
|
移动开发 JavaScript 前端开发
HTML5 MathML好用的第三方库推荐
HTML5 的 MathML 对数学公式的展现至关重要,但因浏览器兼容性和复杂性问题,开发者常选用第三方库增强其功能。本文推荐了四个库:MathJax、KaTeX、MathML Cloud 和 jsMath。MathJax 兼容性好,支持多种格式;KaTeX 渲染速度快,适合现代浏览器;MathML Cloud 提供云端转换服务;jsMath 则适用于基本 MathML 支持。根据项目需求选择合适的库,能显著提升数学内容展示质量和用户体验。
|
机器学习/深度学习 传感器 自动驾驶
使用Python实现深度学习模型:智能车联网与自动驾驶
【8月更文挑战第14天】 使用Python实现深度学习模型:智能车联网与自动驾驶
739 10
|
存储 SQL 测试技术
Entity Framework Core 中的存储过程超厉害!从定义到调用全攻略,提升性能与安全性!
【8月更文挑战第31天】在现代软件开发中,数据库操作效率至关重要。Entity Framework Core(EF Core)作为强大的对象关系映射(ORM)框架,支持存储过程,可提升数据库操作的性能、安全性和可维护性。本文详细介绍如何在 EF Core 中定义、配置及调用存储过程,并提供最佳实践建议,包括性能优化、安全性增强、代码可维护性提升以及参数化查询等。通过遵循这些指导原则,开发者能够充分利用存储过程的优势,显著提高应用程序质量和性能。附带完整示例代码,展示从定义实体类到调用存储过程的全过程。
724 0
Java 获取周,月,年日期集合(统计图)
Java 获取周,月,年日期集合(统计图)
Java 获取周,月,年日期集合(统计图)