首页 新闻 会员 周边 捐助

dotnetty多个websocket客户端发送消息,仅一个接收成功

0
悬赏园豆:10 [已解决问题] 解决于 2021-12-19 20:01
private static Dictionary<string, IChannelHandlerContext> websocketClients = new Dictionary<string, IChannelHandlerContext>();

上面是定义的一个字典用于保存创建websocket连接的客户端。

同时创建了一个Socket连接,用于接收发送给websocket客户端的信息。Socket连接创建之后,启动一个线程,等待socket服务端的消息推送。

接收到推送消息之后,会往websocketClients里的每一个websocket客户端发送消息。

这样子实现,逻辑上看来没有问题。但是调试发现,我在同一台电脑上的,两个浏览器打开,分别创建了2个websocket连接,再用另外一个电脑的浏览器打开创建了一个websocket.

循环往这3个websocket客户端发送消息(写入方法:IChannelHandlerContext.WriteAndFlushAsync)后,只有其中一个客户端能接收到消息。

不知道大家有没有碰到过这种问题呢。

Code_Song的主页 Code_Song | 初学一级 | 园豆:51
提问于:2021-12-19 12:56
< >
分享
最佳答案
0

调试了半天,搞定了。碰到这种需要多播的需求,需要通过IChannelGroup来实现。

对于开始尝试的IChannelHandlerContext,循环发送为何不行。可能只适用于单播的场景,但是还是很迷蒙,有空了再研究一下。

Code_Song | 初学一级 |园豆:51 | 2021-12-19 20:00

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) {
  
    }
}

 

Code_Song | 园豆:51 (初学一级) | 2021-12-20 14:12
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册