Netty 4,无法处理多个客户端

Netty 4,无法处理多个客户端,netty,Netty,我决定找出我的笔记本可以从多个客户机每秒发送多少消息。 我已经用下一种简单的方式从示例中更改了Echo客户端/服务器: 1) 在客户端,channelActive()方法中有无限循环。循环发送消息。 2) 在服务器端,我使用channelRead()方法来处理传入消息 当我运行客户端2次(在2个separet线程中)时,我希望看到服务器如何在2个线程中处理客户端。 相反,服务器只处理1个客户机连接,有时根本不处理。 我查看了客户端线程,发现它们无法退出ChannelOutboundBuffer.

我决定找出我的笔记本可以从多个客户机每秒发送多少消息。 我已经用下一种简单的方式从示例中更改了Echo客户端/服务器: 1) 在客户端,channelActive()方法中有无限循环。循环发送消息。 2) 在服务器端,我使用channelRead()方法来处理传入消息

当我运行客户端2次(在2个separet线程中)时,我希望看到服务器如何在2个线程中处理客户端。 相反,服务器只处理1个客户机连接,有时根本不处理。 我查看了客户端线程,发现它们无法退出ChannelOutboundBuffer.addFlush()方法中的while循环。 我不明白我做错了什么。我使用netty 4.0.21

EchoClient.java

    public static void main(String[] args) throws Exception {
    // Configure the client.
    final EventLoopGroup group = new NioEventLoopGroup();

    Runnable r = new Runnable() {
        @Override
        public void run() {
            try {

                Bootstrap b = new Bootstrap();
                b.group(group)
                        .channel(NioSocketChannel.class)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch) throws Exception {
                                ChannelPipeline p = ch.pipeline();
                                p.addLast(new EchoClientHandler());
                            }
                        });

                // Start the client.
                ChannelFuture f = b.connect(HOST, PORT).sync();

                // Wait until the connection is closed.
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // Shut down the event loop to terminate all threads.
                group.shutdownGracefully();
            }
        }
    };

    for (int i = 0; i < 2; i++) {
        Thread t = new Thread(r, i + " lalala");
        t.start();
    }
}
public class EchoClientHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelActive(ChannelHandlerContext ctx) {
    while (true) {
        ByteBuf time = ctx.alloc().buffer(4);
        time.writeInt(number);
        ctx.writeAndFlush(time);
        ctx.flush();
    }
}


@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
    ctx.flush();
    ctx.fireChannelReadComplete();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    // Close the connection when an exception is raised.
    cause.printStackTrace();
    ctx.close();
    ctx.fireExceptionCaught(cause);
}
public final class EchoServer {

    public static void main(String[] args) throws Exception {

    // Configure the server.
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new EchoServerHandler());
                    }
                });

        // Start the server.
        ChannelFuture f = b.bind(8007).sync();

        // Wait until the server socket is closed.
        f.channel().closeFuture().sync();
    } finally {
        // Shut down all event loops to terminate all threads.
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}
@Sharable
}

EchoServer.java

    public static void main(String[] args) throws Exception {
    // Configure the client.
    final EventLoopGroup group = new NioEventLoopGroup();

    Runnable r = new Runnable() {
        @Override
        public void run() {
            try {

                Bootstrap b = new Bootstrap();
                b.group(group)
                        .channel(NioSocketChannel.class)
                        .option(ChannelOption.TCP_NODELAY, true)
                        .handler(new ChannelInitializer<SocketChannel>() {
                            @Override
                            public void initChannel(SocketChannel ch) throws Exception {
                                ChannelPipeline p = ch.pipeline();
                                p.addLast(new EchoClientHandler());
                            }
                        });

                // Start the client.
                ChannelFuture f = b.connect(HOST, PORT).sync();

                // Wait until the connection is closed.
                f.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // Shut down the event loop to terminate all threads.
                group.shutdownGracefully();
            }
        }
    };

    for (int i = 0; i < 2; i++) {
        Thread t = new Thread(r, i + " lalala");
        t.start();
    }
}
public class EchoClientHandler extends ChannelInboundHandlerAdapter {

@Override
public void channelActive(ChannelHandlerContext ctx) {
    while (true) {
        ByteBuf time = ctx.alloc().buffer(4);
        time.writeInt(number);
        ctx.writeAndFlush(time);
        ctx.flush();
    }
}


@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
    ctx.flush();
    ctx.fireChannelReadComplete();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    // Close the connection when an exception is raised.
    cause.printStackTrace();
    ctx.close();
    ctx.fireExceptionCaught(cause);
}
public final class EchoServer {

    public static void main(String[] args) throws Exception {

    // Configure the server.
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        p.addLast(new EchoServerHandler());
                    }
                });

        // Start the server.
        ChannelFuture f = b.bind(8007).sync();

        // Wait until the server socket is closed.
        f.channel().closeFuture().sync();
    } finally {
        // Shut down all event loops to terminate all threads.
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}
@Sharable
公共类EchoServerHandler扩展ChannelInboundHandlerAdapter{

long max_msg = 10000;
long cur_msg = 0;
long startTime = System.nanoTime();
final int NANOS_IN_SEC = 1000000000;

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
   ReferenceCountUtil.release(msg);

    ++cur_msg;
    if (cur_msg == max_msg) {
        System.out.println("Throughput (msg/sec) : " + max_msg * NANOS_IN_SEC / (System.nanoTime() - startTime));
        cur_msg = 0;
        startTime = System.nanoTime();
    }
}

@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
    ctx.flush();
    ctx.fireChannelReadComplete();
}

}在channelActive(…)方法中不能有无限循环,因为这将阻止用于多个连接的EventLoop。这样,您将基本上阻止使用此EventLoop的所有通道的所有事件处理。

您能解释为什么会发生这种情况吗?我根据我读过的一些文章撰写了自己的“netty working view”。为什么我的客户端在服务器上阻止EventLoop,而所有请求都是异步的?我在服务器上有2个EventLoop。第一个EventLoop创建连接并将其传递给第二个EventLoop,第二个EventLoop有几个线程,我认为它们可以处理2个客户端。因为不允许您收紧在不同通道之间共享的线程。当您执行一段时间(true){}时,就是这种情况。这并不是Netty特有的,而是异步/非阻塞执行的更一般性。