关于ASP.NET Core WebSocket实现集群的思考( 九 )


private async Task HandleAll(string id, object msgBody){_logger.LogInformation($"user {id} send:{msgBody}");//直接给redis的全员频道发送消息ChannelMsgBody channelMsgBody = new ChannelMsgBody { FromId = id, Msg = msgBody.ToString() };_redisClient.Publish(all, JsonConvert.SerializeObject(channelMsgBody));}全员消息的发送数据格式如下所示
{"Method":"All", "MsgBody":"Hello All"}Method为All代表着全员消息类型 , MsgBody则代表着具体消息 。接收消息出里同样很简单 , 订阅redis全员消息频道 , 然后遍历当前WebSocket服务器实例内的所有用户获取连接发送消息 , 具体逻辑如下
private async Task SubAllMsg(string channel){var sub = _redisClient.Subscribe(channel, async (channel, data) =>{ChannelMsgBody msgBody = JsonConvert.DeserializeObject<ChannelMsgBody>(data.ToString());byte[] sendByte = Encoding.UTF8.GetBytes($"user 【{msgBody.FromId}】 send all:{msgBody.Msg}");//获取当前服务器实例内所有用户的连接foreach (var user in UserConnection){//不给自己发送消息 , 因为发送的时候可以通过具体的业务代码处理if (user.Key == msgBody.FromId){continue;}//给每个用户发送消息if (user.Value.State == WebSocketState.Open){await user.Value.SendAsync(new ArraySegment<byte>(sendByte, 0, sendByte.Length), WebSocketMessageType.Text, true, CancellationToken.None);}else{_ = UserConnection.TryRemove(user.Key, out _);}}});_disposables.TryAdd(channel, sub);}示例源码由于篇幅有限 , 没办法设计到全部的相关源码 , 因此在这里贴出来github相关的地址 , 方便大家查看和运行源码 。相关的源码我这里实现了两个版本 , 一个是基于asp.net core的版本 , 一个是基于golang的版本 。两份源码的实现思路是一致的 , 所以这两份代码可以运行在一套集群示例里 , 配置在一套nginx里 , 并且连接到同一个redis实例里即可

  • asp.net core源码示例 https://github.com/softlgl/WebsocketCluster
  • golang源码示例 https://github.com/softlgl/websocket-cluster
仓库里还涉及到本人闲暇之余开源的其他仓库 , 由于本人能力有限难登大雅之堂 , 就不做广告了 , 有兴趣的同学可以自行浏览一下 。
总结本文基于ASP.NET Core框架提供了一个基于WebSocket做集群的示例 , 由于思想是通用的 , 所以基于这个思路楼主也实现了golang版本 。其实在之前就想自己动手搞一搞关于WebSocket集群方面的设计 , 本篇文章算是对之前想法的一个落地操作 。其核心思路文章已经做了相关介绍 , 由于这些只是博主关于构思的实现 , 可能有很多细节尚未体现到 , 还希望大家多多理解 。其核心思路总结一下
  • 首先是 , 利用可以构建WebSocket服务的框架 , 在当前服务实例中保存当前客户端用户和WebSocket的连接关系
  • 如果消息的目标客户端不在当前服务器 , 可以利用redis频道、消息队列相关、甚至是数据库类的共享回话发送的消息 , 由目标服务器获取目标是否属于自己的ws会话
  • 本文设计的思路使用的是无状态的方式 , 即WebSocket服务实例之间不存在直接的消息通信和相互的服务地址存储 , 当然也可以利用redis等存储在线用户信息等 , 这个可以参考具体业务自行设计
读万卷书,行万里路 。在这个时刻都在变化点的环境里 , 唯有不断的进化自己 , 多接触多尝试不用的事物 , 多扩展自己的认知思维 , 方能构建自己的底层逻辑 。毕竟越底层越抽象 , 越通用越抽象 。面对未知的挑战 , 自身作为自己坚强的后盾 , 可能才会让自己更踏实 。

经验总结扩展阅读