Netty ReadComplete()调用了两次
注意:此问题以前曾发布过,但现在使用ChannelOption.MAX_MESSAGES_PER_READ解决方案不起作用。此外,该选项已弃用 注:作为提醒。。我和内蒂是新手 使用Netty4.1.51,当我用“curl-v”刺激下面的代码时http://localhost:8080/'时,我的程序的控制台输出显示:Netty ReadComplete()调用了两次,netty,Netty,注意:此问题以前曾发布过,但现在使用ChannelOption.MAX_MESSAGES_PER_READ解决方案不起作用。此外,该选项已弃用 注:作为提醒。。我和内蒂是新手 使用Netty4.1.51,当我用“curl-v”刺激下面的代码时http://localhost:8080/'时,我的程序的控制台输出显示: Server listening on 8080 Read GET / HTTP/1.1 Host: localhost:8080 User-Agent: curl/7.71.1
Server listening on 8080
Read
GET / HTTP/1.1
Host: localhost:8080
User-Agent: curl/7.71.1
Accept: */*
ReadComplete
Write Hello
flush
ReadComplete
Write Hello
flush
处理程序read()方法被调用一次,readComplete()方法被调用两次,然而,curl似乎对这种交换感到高兴
curl -v http://localhost:8080/
* Trying ::1:8080...
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.71.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 ok
< Content-Type: text/plain
< Content-Length: 5
<
Hello* Connection #0 to host localhost left intact
curl-vhttp://localhost:8080/
*正在尝试::1:8080。。。
*已连接到本地主机(::1)端口8080(#0)
>GET/HTTP/1.1
>主机:本地主机:8080
>用户代理:curl/7.71.1
>接受:*/*
>
*将捆绑包标记为不支持多用途
我似乎不明白发生了什么事。。最近有人遇到过这个问题吗
readComplete()不应该在一次或多次读取后发生一次吗
感谢所有有空闲时间看这个的人
-jmr
private static void bootstrap1(){
int端口=8080;
EventLoopGroup=new NioEventLoopGroup();
ServerBootstrap bootstrap=newserverbootstrap();
独自创立
.集团(集团)
.channel(NioServerSocketChannel.class)
.childHandler(新的通道初始值设定项()
{
@覆盖受保护的通道(SocketChannel ch)
抛出异常
{
ChannelPipeline=通道管道();
addLast(“out”,newouthandler());
addLast(“in”,new InHandler());
}
});
ChannelFuture=bootstrap.bind(新的InetSocketAddress(端口));
future.addListener((ChannelFutureListener)(ChannelFuture1)->
{
if(future1.issucess()){
pr(“服务器侦听”+端口);
}否则{
未来1.原因().printStackTrace();
}
});
}
Handler中的私有静态类扩展ChannelInboundHandlerAdapter{
@凌驾
public void channelRead(ChannelHandlerContext ctx,Object msg)引发异常{
公共关系(“阅读”);
if(msg instanceof ByteBuf){
ByteBuf buf=(ByteBuf)味精;
pr(“+buf.readCharSequence(buf.readableBytes(),Charset.defaultCharset());
}
ctx.fireChannelRead(msg);
}
@覆盖公共无效channelReadComplete(ChannelHandlerContext ctx)
抛出异常
{
pr(“重新完成”);
ByteBuf buf=unmooled.buffer();
buf.writeCharSequence(“Hello”,Charset.defaultCharset());
ctx.writeAndFlush(buf);
ctx.fireChannelReadComplete();
}
}
私有静态类OutHandler扩展了ChannelOutboundHandlerAdapter{
@重写公共无效写入(ChannelHandlerContext ctx,对象消息,
渠道(承诺)
抛出异常
{
ByteBuf in=(ByteBuf)味精;
pr(“Write”+in.getCharSequence(0,in.readableBytes(),Charset.defaultCharset());
ByteBuf buf=unmooled.buffer();
buf.writeCharSequence(“HTTP/1.1 200 ok\r\n”,Charset.defaultCharset());
buf.writeCharSequence(“内容类型:text/plain\r\n”,Charset.defaultCharset());
buf.writeCharSequence(“内容长度:5\r\n\r\n”,Charset.defaultCharset());
buf.writeCharSequence(in.readCharSequence(5,Charset.defaultCharset()),Charset.defaultCharset());
in.release();
ctx.write(buf);
}
@覆盖公共无效刷新(ChannelHandlerContext ctx)
抛出异常
{
公共关系(“同花顺”);
ctx.flush();
}
}
除了调用两次channelReadComplete
之外,您还编写了两次HTTP响应,这由重复的“Write Hello”日志消息指示
channelReadComplete
被调用两次,因为自动读取已打开(默认情况下会发生)。要关闭该选项并触发初始只读,您可以修改通道初始值设定项
,如下所示:
.childHandler(new ChannelInitializer<SocketChannel>()
{
@Override protected void initChannel(SocketChannel ch)
throws Exception
{
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("out", new OutHandler());
pipeline.addLast("in", new InHandler());
ch.config().setAutoRead(false);
ch.read();
}
});
.childHandler(新的通道初始值设定项()
{
@覆盖受保护的通道(SocketChannel ch)
抛出异常
{
ChannelPipeline=通道管道();
addLast(“out”,newouthandler());
addLast(“in”,new InHandler());
ch.config().setAutoRead(false);
ch.read();
}
});
话虽如此,channelReadComplete
并不是创建和发送响应的正确位置。在您的情况下,这样做会导致双重发送响应。卷曲也许可以,但这不是你想要的。一旦收集到完整的请求,channelRead
方法是发送响应的更好地方
有关参考echo服务器,请查看以下内容:
我强烈推荐NIA的书,让你在所有的事情上都能找到正确的方向
.childHandler(new ChannelInitializer<SocketChannel>()
{
@Override protected void initChannel(SocketChannel ch)
throws Exception
{
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("out", new OutHandler());
pipeline.addLast("in", new InHandler());
ch.config().setAutoRead(false);
ch.read();
}
});