[英]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.