Netty - 如何获取所有客户端通道?

11

我正在使用Netty的示例代码-Telnet包,现在这段代码可以建立服务器和客户端,使用telnet进行聊天,但客户端只能与服务器交谈。 我正在重写它以使客户端可以向所有客户端说话,因此我需要保留一个通道列表,这样当客户端联系服务器时,服务器就可以将消息发送给所有客户端。

请问有人可以告诉我如何获取所有客户端通道吗?

(示例代码参考此处链接


你成功获取了所有客户端通道了吗? - Jose Ramon
4个回答

15

对于Netty 4.0.X版本

在主类中,您需要声明ChannelGroup对象:

 final ChannelGroup channels = 
                new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

当一个新的客户端连接时(你应该在构造函数中将通道对象传递给你的处理程序类):

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
    channels.add(ctx.channel());
}

要获取所有客户端,只需迭代通道对象:

for (Channel ch : channels) {
    //do something with ch object
}
希望它有所帮助。

7

Mauricio 的提议很好。此外,Netty API 已经在 ChannelGroup 中提供了一个通道容器。它是线程安全的,并且还提供了一些额外的功能,例如对所有包含的通道进行组操作以及在关闭这些通道时自动删除它们。从 javadoc 中可以看出:

一个线程安全的集合,其中包含打开的通道并提供各种批量操作。使用 ChannelGroup,您可以将通道分类到有意义的组中(例如按每个服务或每个状态分组)。关闭的通道会自动从集合中删除,因此您不需要担心已添加通道的生命周期。通道可以属于多个 ChannelGroup。


3

这里是一个小例子(覆盖了SimpleChannelUpstreamHandler的channelConnected方法):

ChannelGroup allConnected = new DefaultChannelGroup("all-connected");

@Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
    super.channelConnected(ctx, e);
    allConnected.add(e.getChannel());
}

现在您可以这样向所有连接的频道发送消息:

    ChannelBuffer cb = ChannelBuffers.wrappedBuffer("hello".getBytes(Charset.forName("UTF-8")));
    allConnected.write(cb);

对于Netty 4/5,javadoc中有一个类似的示例,http://netty.io/4.0/api/io/netty/channel/group/ChannelGroup.html,它重写了channelActive()方法,并在添加通道之后调用了超级方法。 - Stefan L
@StefanL 根据文档中的示例,我该如何获取客户端的频道?(例如:channelA、channelB..) - hcarrasko

1
channelConnected事件中,从ChannelHandlerContext获取客户端并将其存储在某个地方(并发集合很好用,例如ConcurrentHashMap)。您还需要实现channelClosed方法以从集合中删除已断开连接的通道。

谢谢,我一开始尝试了,但失败了,因为我不知道实现ChannelPipelineFactory生成Handler的方法,通过在正确位置构建通道存储,我成功地做到了。无论如何,非常感谢:) - chentingpc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接