简体   繁体   English

没有调用Netty编码器

[英]Netty Encoder Not Being Called

Using Netty 4.0.27 & Java 1.8.0_20 使用Netty 4.0.27和Java 1.8.0_20

So I am attempting to learn how Netty works by building a simple chat server (the typical networking tutorial program, I guess?). 因此,我试图通过构建一个简单的聊天服务器(我想是典型的网络教程程序)来学习Netty的工作原理。 Designing my own simple protocol, called ARC (Andrew's Relay Chat)... so that's why you see ARC in the code a lot. 设计我自己的简单协议,称为ARC(安德鲁的中继聊天)...因此,您经常在代码中看到ARC。 K, so here's the issue. K,所以这是问题。

So here I start the server and register the various handlers... 所以在这里我启动服务器并注册各种处理程序...

    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();
        }
    }

My "inboundHandler" does get called when the user connects. 我的“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);
}

This is my encoder, which does not seem to get called at all... 这是我的编码器,似乎根本没有被调用...

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;
    }
}

So, 所以,

The code that calls ctx.writeAndFlush(packet); 调用ctx.writeAndFlush(packet);的代码 is run, but it doesn't seem to invoke the encoder at any point. 运行,但似乎在任何时候都没有调用编码器。 Am I missing something obvious? 我是否缺少明显的东西? Perhaps I'm adding the encoder incorrectly? 也许我添加的编码器不正确? Though it looks right when I compare it to other examples I've seen. 虽然将其与我看到的其他示例进行比较看起来不错。

Thanks for any help. 谢谢你的帮助。

Your encoder ( ArcEncoder ) is placed after your inbound handler. 编码器( ArcEncoder )放置入站处理程序之后。 It means, the ctx.*() method calls will never be evaluated by the encoder. 这意味着ctx.*()方法调用将永远不会被编码器评估。 To fix your problem, you have to move the ArcEncoder before the inbound handler: 要解决您的问题,您必须将ArcEncoder移动到入站处理程序之前:

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

For more information about the event evaluation order, please read the API documentation of ChannelPipeline . 有关事件评估顺序的更多信息,请阅读ChannelPipeline的API文档

I think the problem is that you're using the ChannelHandlerContext to write to the Channel. 我认为问题在于您正在使用ChannelHandlerContext写入Channel。 What this does is to insert the message in the pipeline at the point of your handler, going outbound. 这样做是在处理程序的位置将消息插入管道中,出站。 But since your decoder is added before your encoder in the pipeline this means that anything you write using the decoder context will be inserted after the encoder in the pipeline. 但是由于解码器是在管道中的编码器之前添加的,这意味着使用解码器上下文编写的所有内容都将插入管道中的编码器之后

The correct way to do it to ensure that the encoder is called is to call: 确保调用编码器的正确方法是调用:

ctx.channel.writeAndFlush()

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

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