Netty channelRead0 未触发

Netty channelRead0 not firing

我以前从未使用过 Netty,但我创建了一个 Netty 服务器。当我向它发送内容时,channelRead0 永远不会被触发;只有频道阅读。为什么会这样,我该如何触发它?我正在使用 netty 版本 4.0.12。谢谢!

服务器:

void run() {

    EventLoopGroup bossGroup = new NioEventLoopGroup();
    EventLoopGroup workerGroup = new NioEventLoopGroup();

    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .childHandler(new UTFServerInitializer());

        ChannelFuture f = b.bind(this.port).sync();
        f.channel().closeFuture().sync();

    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }

}

初始化处理程序:

static class UTFServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {

        ChannelPipeline pipeline = channel.pipeline();

        pipeline.addLast("UTFHandler", new UTFServerHandler());
    }

}

呼叫处理程序:

static class UTFServerHandler extends SimpleChannelInboundHandler<String> {

    @Override
    public void channelRead(ChannelHandlerContext arg0, Object arg1)
            throws Exception {

        ByteBuf in = (ByteBuf) arg1;

        try {
            while (in.isReadable()) {
                System.out.print((char) in.readByte());
                System.out.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    @Override
    protected void channelRead0(ChannelHandlerContext arg0, String arg1)
            throws Exception {
        // TODO Auto-generated method stub

        // not fired
        System.out.println("channelRead0");

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx)
            throws Exception {
        super.channelReadComplete(ctx);
        System.out.println("channelReadComplete");

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

}

只需将所有业务逻辑放在 channelRead0 方法中,然后删除 channelRead 方法。在这种情况下,默认会调用channelRead0。

您覆盖了 channelRead 方法。在 SimpleChannelInboundHandler 中,有一个模板方法可以调用您的 channelRead0 实现。

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    boolean release = true;
    try {
        if (acceptInboundMessage(msg)) {
            @SuppressWarnings("unchecked")
            I imsg = (I) msg;
            channelRead0(ctx, imsg);
        } else {
            release = false;
            ctx.fireChannelRead(msg);
        }
    } finally {
        if (autoRelease && release) {
            ReferenceCountUtil.release(msg);
        }
    }
}

SimpleChannelInboundHandler 拦截您的 typeName 专用的特定类型的消息,例如 SimpleChannelInboundHandler<Integer> 拦截 Integer。并且您需要在此处理程序之前将 StringDecoder 添加到管道以将 ByteBuf 转换为 String。