我正试图从Mina转移到Netty 4并尝试实现101包含帧长度的标题组成的二进制帧解码器。作为Netty的完整新手,我在网上找到了一个例子并尝试执行它。我必须做一个新手错误,因为代码根据我的期望不起作用。这是代码:
public class NettyNioServer {
public void server(int port) throws Exception {
ServerBootstrap b = new ServerBootstrap();
try {
b.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_KEEPALIVE, true)
.localAddress(new InetSocketAddress(port))
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(1048576, 0, 2, 0, 2));
p.addLast("bytesDecoder", new ByteArrayDecoder());
p.addLast(new NioHandler());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} finally {
b.group()
.shutdownGracefully().sync();
}
}
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.err.println(
"Usage: " + NettyNioServer.class.getSimpleName() +
" <port>");
return;
}
int port = Integer.parseInt(args[0]);
System.out.println("start on port: "+port);
new NettyNioServer().server(port);
}
}
处理程序代码如下:
public class NioHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
byte[] bytes = (byte[]) msg;
System.out.println(bytes.length+" bytes received");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ByteBuf buf1 =Unpooled.copiedBuffer("Well received bye! \r\n", Charset.forName("UTF-8"));
ctx.writeAndFlush(buf1.duplicate()).addListener(ChannelFutureListener.CLOSE);
System.out.println("Answer send");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("Exception caught: "+ cause.getMessage());
}
}
以下是我收到的内容:
start on port: 7777
janv. 02, 2016 8:15:47 PM io.netty.handler.logging.LoggingHandler channelRegistered
INFOS: [id: 0x01f2254e] REGISTERED
janv. 02, 2016 8:15:47 PM io.netty.handler.logging.LoggingHandler bind
INFOS: [id: 0x01f2254e] BIND(0.0.0.0/0.0.0.0:7777)
janv. 02, 2016 8:15:47 PM io.netty.handler.logging.LoggingHandler channelActive
INFOS: [id: 0x01f2254e, /0:0:0:0:0:0:0:0:7777] ACTIVE
janv. 02, 2016 8:17:14 PM io.netty.handler.logging.LoggingHandler logMessage
INFOS: [id: 0x01f2254e, /0:0:0:0:0:0:0:0:7777] RECEIVED: [id: 0x47c24c03, /127.0.0.1:50737 => /127.0.0.1:7777]
Answer send
为什么我的channelRead从未执行过?
答案 0 :(得分:1)
您的处理程序实现似乎是正确的。
因此,此处理程序上没有读取任何数据。这是因为在管道之前的另一个处理程序捕获数据(可能是为了处理它)但它没有完成并且不会为管道上的其他处理程序推送数据。
确保根据LengthFieldBasedFrameDecoder
规范在输入中正确写入数据:http://netty.io/4.0/api/io/netty/handler/codec/LengthFieldBasedFrameDecoder.html
如果你真的不需要,可以删除这个解码器。
您还可以添加管道的LoggingHandler顶部,以通过添加以下内容来查看收到的内容:
p.addFirst("logHandler", new LoggingHandler(LogLevel.INFO));
仅供参考,您的NioHandler还可以扩展SimpleChannelInboundHandler而不是更通用的ChannelInboundHandler