private static Dictionary<string, IChannelHandlerContext> websocketClients = new Dictionary<string, IChannelHandlerContext>();
上面是定义的一个字典用于保存创建websocket连接的客户端。
同时创建了一个Socket连接,用于接收发送给websocket客户端的信息。Socket连接创建之后,启动一个线程,等待socket服务端的消息推送。
接收到推送消息之后,会往websocketClients里的每一个websocket客户端发送消息。
这样子实现,逻辑上看来没有问题。但是调试发现,我在同一台电脑上的,两个浏览器打开,分别创建了2个websocket连接,再用另外一个电脑的浏览器打开创建了一个websocket.
循环往这3个websocket客户端发送消息(写入方法:IChannelHandlerContext.WriteAndFlushAsync)后,只有其中一个客户端能接收到消息。
不知道大家有没有碰到过这种问题呢。
调试了半天,搞定了。碰到这种需要多播的需求,需要通过IChannelGroup来实现。
对于开始尝试的IChannelHandlerContext,循环发送为何不行。可能只适用于单播的场景,但是还是很迷蒙,有空了再研究一下。
1、定义ChannelGroup的字典集合,保存对应多个推送组
public static ConcurrentDictionary<string, IChannelGroup> ChannelGroups = new ConcurrentDictionary<string, IChannelGroup>();
2、在websocket客户端发送绑定消息时,进行channel注册
if (!ChannelGroups.ContainsKey(bind.Code)) { var group = new DefaultChannelGroup(ctx.Executor); group.Add(ctx.Channel); if (!ChannelGroups.TryAdd(bind.Code, group)) { } } else { ChannelGroups[bind.Code].Add(ctx.Channel); }
3、在向websocket客户端发送消息时,找到对应的channelGroup发送消息
var channelGroup = WebSocketServerHandler.ChannelGroups[client]; if (channelGroup != null) { try { await channelGroup.WriteAndFlushAsync(frame); } catch (ChannelGroupException ex) { } }