.NET Core下使用SignalR

2018 年 12 月 4 日 DotNet

(给DotNet加星标,提升.Net技能


转自:cgyqu

cnblogs.com/cgyqu/p/9563193.html


背景


由于要做微信小程序聊天,所以.NetFramwork版本的SignalR版本的不能用了。因为小程序里没有windows对象,导致JQuery无法使用。而Signalr的 js客户端是依赖JQuery的。



services.AddCors(options => options.AddPolicy("SignalR",
  builder =>
  {
      builder.AllowAnyMethod() //允许任意请求方式
             .AllowAnyHeader() //允许任意header
             .AllowAnyOrigin() //允许任意origin
             .AllowCredentials();//允许验证
           //.WithOrigins(domins) //指定特定域名才能访问
  }));


然后在Configure使用定义好的跨域策略


app.UseCors("SignalR");



services.AddSignalR()
       .AddMessagePackProtocol()
       .AddRedis(o =>
       {
           o.ConnectionFactory = async writer =>
           {
               var config = new ConfigurationOptions
               {
                   AbortOnConnectFail = false
               };
               config.EndPoints.Add(IPAddress.Loopback, 0);
               config.SetDefaultPorts();
               var connection = await ConnectionMultiplexer.ConnectAsync(config, writer);
               connection.ConnectionFailed += (_, e) =>
               {
                  Console.WriteLine("Connection Redis failed.");
               };
               if (!connection.IsConnected)
               {
                   Console.WriteLine("Connection did not connect.");
               }
               return connection;
           };
       });



proxy_http_version   1.1;
proxy_set_header  Host $host;
proxy_set_header   Upgrade $http_upgrade;
proxy_set_header   Connection "upgrade";
proxy_connect_timeout   300;
proxy_read_timeout   300;
proxy_send_timeout   300;


于是我把应用发布到本地虚拟机里,并用docker方式运行。然后把配置写进nginx配置文件里。


发现真的不能进行POST请求了,返回400。400的意是思请求异常。肯定是这个配置有问题额。于是又去交友网站找issue,果然又让我找到了。 


在一个issue里面,提供的配置如下


proxy_http_version   1.1;
proxy_set_header   Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;



于是又去看issues,果然,里面也有人问,作者也有解释。


去交友网站看看(https://github.com/aspnet/SignalR/issues/2729)


大体意思ConnectonId是服务端使用,客户端不应该使用这种不可控的方式进行通信。 可以采用Group或者User这种可控方式通信,并且也有例子给出。


这里插一句,在使用.Net Framwork版本时候,我们网站是使用ConnectionId进行通信,经常出现重连导致ConnectionId变掉,进而通信失败。


所以我也调整了下设计思路,改使用Group进行通信。


以上都搞定了,辛苦了这么久,按道理应该没问题了吧!那么发布上线!




看到这个错误,第一个反应,我的想法是难道是Redis没连接成功,所以只能单机跑?所以我就在上面Redis代码加上各种监控,发现连接成功了。代码Review了n遍代码,实在没有地方可以改了。


于是官方文档一个个过。终于发现Js可以进行以下配置


let connection = new signalR.HubConnectionBuilder()
   .withUrl("/myhub", {
       skipNegotiation: true,
       transport: signalR.HttpTransportType.WebSockets
   });
   .build();



private async Task<HttpConnectionContext> GetConnectionAsync(HttpContext context)
{
   var connectionId = GetConnectionId(context);
   if (StringValues.IsNullOrEmpty(connectionId))
   {
       // There's no connection ID: bad request
       context.Response.StatusCode = StatusCodes.Status400BadRequest;
       context.Response.ContentType = "text/plain";
       await context.Response.WriteAsync("Connection ID required");
       return null;
   }
   if (!_manager.TryGetConnection(connectionId, out var connection))
   {
       // No connection with that ID: Not Found
       context.Response.StatusCode = StatusCodes.Status404NotFound;
       context.Response.ContentType = "text/plain";
       await context.Response.WriteAsync("No Connection with that ID");
       return null;
   }
   return connection;
}


这段代码啥意思呢?就是connection在本地没找到的话,就返回404!


我去,难道是代码bug?



啥意思呢?就是这不是bug,就是这么设计的。使用SignalR时,要进行会话保持,请求要一直落到同一台服务器上。这样更稳定,并且还可以实时监控客户端的情况。


于是找运维同学在负载上配置了下会话保持,再次测试,终于可以了。


总结


在此次使用SignalR的过程中,遇到了太多的坑。花了几个小时整理并记录下来,与各位进行分享。


推荐阅读

(点击标题可跳转阅读)

.NET Core SignalR 初体验

ASP.NET Core SignalR中的流式传输

使用 ASP.NET Core SignalR 实现社交网络式通知


看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

登录查看更多
0

相关内容

【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
194+阅读 · 2020年6月29日
可解释强化学习,Explainable Reinforcement Learning: A Survey
专知会员服务
129+阅读 · 2020年5月14日
《动手学深度学习》(Dive into Deep Learning)PyTorch实现
专知会员服务
119+阅读 · 2019年12月31日
【ICLR2020】五篇Open代码的GNN论文
专知会员服务
47+阅读 · 2019年10月2日
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
基于Web页面验证码机制漏洞的检测
FreeBuf
7+阅读 · 2019年3月15日
I2P - 适用于黑客的Android应用程序
黑白之道
30+阅读 · 2019年3月6日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
51+阅读 · 2018年12月20日
.NET Core 环境下构建强大且易用的规则引擎
浅谈浏览器 http 的缓存机制
前端大全
6+阅读 · 2018年1月21日
干货|全文检索Solr集成HanLP中文分词
全球人工智能
4+阅读 · 2017年8月27日
Deep Reinforcement Learning: An Overview
Arxiv
17+阅读 · 2018年11月26日
Hierarchical Deep Multiagent Reinforcement Learning
Arxiv
8+阅读 · 2018年9月25日
Arxiv
5+阅读 · 2018年4月22日
Arxiv
6+阅读 · 2018年1月11日
VIP会员
相关VIP内容
【实用书】学习用Python编写代码进行数据分析,103页pdf
专知会员服务
194+阅读 · 2020年6月29日
可解释强化学习,Explainable Reinforcement Learning: A Survey
专知会员服务
129+阅读 · 2020年5月14日
《动手学深度学习》(Dive into Deep Learning)PyTorch实现
专知会员服务
119+阅读 · 2019年12月31日
【ICLR2020】五篇Open代码的GNN论文
专知会员服务
47+阅读 · 2019年10月2日
相关资讯
使用 C# 和 Blazor 进行全栈开发
DotNet
6+阅读 · 2019年4月15日
基于Web页面验证码机制漏洞的检测
FreeBuf
7+阅读 · 2019年3月15日
I2P - 适用于黑客的Android应用程序
黑白之道
30+阅读 · 2019年3月6日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
51+阅读 · 2018年12月20日
.NET Core 环境下构建强大且易用的规则引擎
浅谈浏览器 http 的缓存机制
前端大全
6+阅读 · 2018年1月21日
干货|全文检索Solr集成HanLP中文分词
全球人工智能
4+阅读 · 2017年8月27日
Top
微信扫码咨询专知VIP会员