【问题标题】:Last Netty 4.1 client blocked最后一个 Netty 4.1 客户端被阻止
【发布时间】:2016-11-26 20:33:38
【问题描述】:

我有以下创建Netty 4.1客户端的方法:

public void runClient() throws Exception {
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    try {
        final ClientClassHandler cch = new ClientClassHandler();
        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("frameDecoder",
                        new ProtobufVarint32FrameDecoder());
                ch.pipeline().addLast("protobufDecoder",
                        new ProtobufDecoder(Client.MyMessage.getDefaultInstance()));
                ch.pipeline().addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender());
                ch.pipeline().addLast("protobufEncoder", new ProtobufEncoder());
                ch.pipeline().addLast("handler", cch);
                ch.pipeline().addLast(new CommonClassHandler());
            }
        });

        Player player = new Player();
        cch.setPlayer(player);
        player.createMap();

        Channel channel = b.connect(HOST, PORT).sync().channel();
        player.setChan(channel);

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        // Waits for user input, then fills the Protocol Buffers build and sends it.
        while (channel.isOpen()) {
            String input = in.readLine();
            player.handleInput(input); // Checks if input is OK and sends it to server
        }

        channel.closeFuture().sync();

    } finally {
        workerGroup.shutdownGracefully();
    }
}

但是当第 4 个客户端加入服务器时,服务器会启动一个游戏循环,而这个循环似乎会阻止最后一个客户端的输入到达服务器。

输入被发送到服务器,如下所示:

  serverChannel.writeAndFlush(message.build());

但它永远不会到达

  @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    Server.MyMessage req = (Server.MyMessage) msg;

    protocol.handleInput(req, ctx); // Checks if input of client is OK
    System.out.println(req.getKeyword());
}

方法,仅在循环停止或不存在时执行。

我认为我的服务器不会因为循环而被这样阻塞。我错过了什么吗?

【问题讨论】:

    标签: java netty


    【解决方案1】:

    这个问题是因为你直接从channelRead方法开始游戏循环造成的。

    只要channelRead方法中有1个线程,netty就不能接受该通道的其他输入,以防止排序和线程安全错误。

    您应该生成一个自定义线程来处理您的游戏循环,或者挂钩到该组的事件执行器以获取一个专用线程用于您的循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      • 2015-09-10
      • 2015-07-04
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多