簡體   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