我以前从未与Netty合作,而且我创建了一个Netty服务器。当我发送内容时,channelRead0永远不会被解雇;只有channelRead。为什么这样,我怎么能触发它?我使用的是netty 4.0.12版。谢谢!
服务器:
void run() {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.childHandler(new UTFServerInitializer());
ChannelFuture f = b.bind(this.port).sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
初始化处理程序:
static class UTFServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("UTFHandler", new UTFServerHandler());
}
}
呼叫处理程序:
static class UTFServerHandler extends SimpleChannelInboundHandler<String> {
@Override
public void channelRead(ChannelHandlerContext arg0, Object arg1)
throws Exception {
ByteBuf in = (ByteBuf) arg1;
try {
while (in.isReadable()) {
System.out.print((char) in.readByte());
System.out.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
@Override
protected void channelRead0(ChannelHandlerContext arg0, String arg1)
throws Exception {
// TODO Auto-generated method stub
// not fired
System.out.println("channelRead0");
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
throws Exception {
super.channelReadComplete(ctx);
System.out.println("channelReadComplete");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
cause.printStackTrace();
ctx.close();
}
}
答案 0 :(得分:4)
您覆盖channelRead方法。在SimpleChannelInboundHandler中,有一个模板方法可以调用你的channelRead0实现。
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
boolean release = true;
try {
if (acceptInboundMessage(msg)) {
@SuppressWarnings("unchecked")
I imsg = (I) msg;
channelRead0(ctx, imsg);
} else {
release = false;
ctx.fireChannelRead(msg);
}
} finally {
if (autoRelease && release) {
ReferenceCountUtil.release(msg);
}
}
}
SimpleChannelInboundHandler拦截您的typeName专用的某种类型的消息,例如SimpleChannelInboundHandler<Integer>
拦截整数。并且您需要在此处理程序之前将StringDecoder添加到管道,以将ByteBuf转换为String。
答案 1 :(得分:3)
将所有业务逻辑放在channelRead0方法中,然后删除 channelRead方法。在这种情况下,默认情况下将调用channelRead0。