繁体   English   中英

没有调用Netty编码器

[英]Netty Encoder Not Being Called

使用Netty 4.0.27和Java 1.8.0_20

因此,我试图通过构建一个简单的聊天服务器(我想是典型的网络教程程序)来学习Netty的工作原理。 设计我自己的简单协议,称为ARC(安德鲁的中继聊天)...因此,您经常在代码中看到ARC。 K,所以这是问题。

所以在这里我启动服务器并注册各种处理程序...

    public void start()
    {
        System.out.println("Registering handlers...");
        ArcServerInboundHandler inboundHandler = new ArcServerInboundHandler(this);

        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try
        {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>()
            {
                @Override
                public void initChannel(SocketChannel ch) throws Exception
                {
                    ch.pipeline().addLast(new ArcDecoder(), inboundHandler);
                    ch.pipeline().addLast(new ArcEncoder());
                }
            }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);

            try
            {
                System.out.println("Starting Arc Server on port " + port);
                ChannelFuture f = bootstrap.bind(port).sync();
                f.channel().closeFuture().sync();
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        finally
        {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }

我的“inboundHandler” 确实当用户将被调用。

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception
{
    System.out.println("CLIENT CONNECTED"); // THIS PRINTS, REACHES THIS POINT
    ArcPacket packet = new ArcPacket();
    packet.setArc("PUBLIC_KEY");
    packet.setField("KEY", Crypto.bytesToHex(server.getRsaKeys().getPublic().getEncoded()));
    ctx.writeAndFlush(packet);
}

这是我的编码器,似乎根本没有被调用...

public class ArcEncoder extends MessageToByteEncoder<ArcPacket>
{
    @Override
    protected void encode(ChannelHandlerContext ctx, ArcPacket msg, ByteBuf out) throws Exception
    {
        System.out.println("ENCODE"); // NEVER GETS HERE
        String message = ArcPacketFactory.encode(msg);
        byte[] data = message.getBytes("UTF-8");
        out.writeBytes(data);
        System.out.println("WROTE");
    }

    @Override
    public boolean acceptOutboundMessage(Object msg) throws Exception
    {
        System.out.println("ACCEPT OUTBOUND MESSAGE"); // NEVER GETS HERE
        return msg instanceof ArcPacket;
    }
}

所以,

调用ctx.writeAndFlush(packet);的代码 运行,但似乎在任何时候都没有调用编码器。 我是否缺少明显的东西? 也许我添加的编码器不正确? 虽然将其与我看到的其他示例进行比较看起来不错。

谢谢你的帮助。

编码器( ArcEncoder )放置入站处理程序之后。 这意味着ctx.*()方法调用将永远不会被编码器评估。 要解决您的问题,您必须将ArcEncoder移动到入站处理程序之前:

ch.pipeline().addLast(new ArcDecoder(), new ArcEncoder(), inboundHandler);

有关事件评估顺序的更多信息,请阅读ChannelPipeline的API文档

我认为问题在于您正在使用ChannelHandlerContext写入Channel。 这样做是在处理程序的位置将消息插入管道中,出站。 但是由于解码器是在管道中的编码器之前添加的,这意味着使用解码器上下文编写的所有内容都将插入管道中的编码器之后

确保调用编码器的正确方法是调用:

ctx.channel.writeAndFlush()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM