我想在Netty nio中创建一个具有两个客户端和一个服务器的通信系统。更具体地说,首先,我希望当两个客户端与服务器连接时从服务器发送一条消息,然后在这两个客户端之间交换数据。我正在使用code provided from this example。我对代码的修改可以在这里找到:link

当第一个客户端连接时,serverHandler中的channelRead似乎可以正常工作,因此它始终返回1,但是当连接第二个客户端时,它不会更改为2。当两个客户端都连接到服务器时,如何从服务器正确检查?如何从客户端的主要功能动态读取此值?那么,让两个客户交流的最佳方法是什么?

编辑1:显然,客户端服务正在运行并直接关闭,因此每次我运行新的NettyClient时都已连接,但此后该连接已关闭。因此,计数器始终从零到1变动。正如我在以下评论中所建议的那样,我在同一端口上使用telnet对其进行了测试,但是计数器似乎正常增加,但是使用NettyClient服务没有。

编辑2:似乎我遇到的问题来自future.addListener(ChannelFutureListener.CLOSE);channelRead中的ProcessingHandler class。当我发表评论时,代码似乎可以正常工作。但是,不确定将其注释掉会带来什么后果。此外,我想从客户端的主要功能中检查返回消息何时是特定的两个。我该如何创建一种方法来等待服务器发出特定消息,同时又阻止主要功能。

 static EventLoopGroup workerGroup = new NioEventLoopGroup();
 static Promise<Object> promise = workerGroup.next().newPromise();
 public static void callClient() throws Exception {
    String host = "localhost";
    int port = 8080;
    try {
        Bootstrap b = new Bootstrap();
        b.group(workerGroup);
        b.channel(NioSocketChannel.class);
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new RequestDataEncoder(), new ResponseDataDecoder(), new ClientHandler(promise));
            }
        });
        ChannelFuture f = b.connect(host, port).sync();
    } finally {
        //workerGroup.shutdownGracefully();
    }
}

我希望在main函数内部调用该方法并返回结果,并在结果为2时继续使用main函数。但是,我无法在一段时间内调用callClient,因为它将在同一个客户端上运行多次。
   callBack();
    while (true) {
        Object msg = promise.get();
        System.out.println("Case1: the connected clients is not two");
        int ret = Integer.parseInt(msg.toString());
        if (ret == 2){
            break;
        }
    }
   System.out.println("Case2: the connected clients is two");
   // proceed with the main functionality

如何为第一个客户端更新promise变量。当我运行两个客户端时,对于第一个客户端,我总是收到以下消息:



似乎 promise 没有正常更新,而对于第二个客户,我总是收到:

最佳答案

如果我的内存正确,则ChannelHandlerContext每个 channel 一个,并且它的管道中可以有多个ChannelHandlers。您的channel变量是处理程序类的实例变量。然后为每个连接创建一个新的ProcessingHandler实例。因此,一旦初始化,每个人在channels变量中将只有一个连接-它是为它创建的。

请参阅服务器代码(NettyServer.java)中initChannel函数中的new ProcessingHandler()

您可以将channels变量设为静态,以便在ProcessingHandler实例之间共享它。或者,您可以在其他地方创建单个ProcessingHandler实例(例如,作为run()函数中的局部变量),然后将该实例传递给addLast调用而不是new ProcessingHandler()

08-27 14:56