【问题标题】:netty server receive two http content but they are should combine to onenetty 服务器接收两个 http 内容,但它们应该合并为一个
【发布时间】:2015-10-27 16:39:42
【问题描述】:
12:19:22.737 [nioEventLoopGroup-3-10] ERROR ********************************* - get http content failed, expect 29, actual 9
12:19:22.737 [nioEventLoopGroup-3-10] ERROR ********************************* - converty request DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
POST /rpc/gdt.marvel.MarvelIncreService.FetchData HTTP/1.1
Content-Type: application/x-protobuf
Rpc-SeqNo: 497
Content-Length: 29 failed 
12:19:22.738 [nioEventLoopGroup-3-10] ERROR ********************************* - get http content failed, expect 29, actual 20
12:19:22.738 [nioEventLoopGroup-3-10] ERROR ********************************* - converty request DefaultHttpRequest(decodeResult: success, version: HTTP/1.1)
POST /rpc/gdt.marvel.MarvelIncreService.FetchData HTTP/1.1
Content-Type: application/x-protobuf
Rpc-SeqNo: 497
Content-Length: 29 failed 

以上是日志。从日志中我们可以看到客户端发送的seqNo都是497,并且确实发送过一次。但是从用netty搭建的Server中,我们收到了两个http内容。因此,它们的长度都与标头中的 Content-Length 不一致。但是两个内容长度 9 + 20 = 29,应该合二为一。

以下是我的服务器处理程序代码,任何人都可以帮助我吗?

 60 public class RpcNettyServerHandler extends ChannelInboundHandlerAdapter {       
 61     
  -----
 92   @Override                                                                     
 93   public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {     
 94     LOG.error("Exception happend on netty http handler {}", cause.toString());  
 95     cause.printStackTrace();                                                    
 96     ctx.close();                                                                
 97   }                                                                             
 98                                                                                 
 99   @Override                                                                     
100   public void channelReadComplete(ChannelHandlerContext ctx) {                  
101     ctx.flush();                                                                
102   }                                                                             
103                                                                                 
104   @Override                                                                     
105   public void channelRead(ChannelHandlerContext ctx, Object msg) {              
106     if (msg instanceof HttpRequest) {                                    

      ---
140     if (msg instanceof HttpContent) {                                           
141       HttpContent httpContent = (HttpContent) msg;                              
142       if (this.httpMethod == POST) {                                            
143         handleRpc(ctx, httpRequest, httpContent);                               
144       } else if (this.httpMethod == GET) {                                      
145         handleForm(httpRequest, httpContent);                                   
146       }                                                                         
147     }                                                                           
148   }                     

基本上,我们用netty做实现了一个http rpc服务器,实现很简单,但是从日志中,我们看到了连线的东西。感谢您的帮助

如下,我已经使用http编解码器来处理http协议,netty.*.http中提供了该协议

 8 import io.netty.channel.ChannelInitializer;                                     
  9 import io.netty.channel.ChannelPipeline;                                        
 10 import io.netty.channel.socket.SocketChannel;                                   
 11 import io.netty.handler.codec.http.HttpServerCodec;                             
 12 import io.netty.handler.ssl.SslContext;                                         
 13                                                                                 
 14 public class RpcNettyServerInitializer extends                                  
 15     ChannelInitializer<SocketChannel> {                                         
 16                                                                                 
 17   private RpcHandlerRegistryImpl handlerRegistry;                               
 18                                                                                 
 19   public RpcNettyServerInitializer(RpcHandlerRegistryImpl handlerRegistry) {    
 20     this.handlerRegistry = handlerRegistry;                                     
 21   }                                                                             
 22                                                                                 
 23   @Override                                                                     
 24   public void initChannel(SocketChannel ch) {                                   
 25     ChannelPipeline p = ch.pipeline();                                          
 26     p.addLast(new HttpServerCodec());                                           
 27     p.addLast(new RpcNettyServerHandler(this.handlerRegistry));                 
 28   }                                                                             
 29                                                                                 
 30 }              

【问题讨论】:

  • 你的假设是错误的。没有什么说应该一次性交付。
  • 我该如何处理这种情况?请帮帮我
  • 只需在您的管道中添加聚合器:请参阅我编辑的答案中的示例...

标签: java netty


【解决方案1】:

您应该使用 HttpObjectAggregator 以便将多个内容(块)放入一个响应或请求中。当然,你也应该使用http编解码器,客户端或服务器,取决于你的身边......

编辑:如果你不使用聚合器,你必须自己处理多个块(httpContent)。

在您的情况下,您可能有 2 个块,但尝试在加载所有块之前处理请求...

管道示例:

p.addLast(new HttpServerCodec());
p.addLast("aggregator", new HttpObjectAggregator(1048576));
p.addLast(new YourHandler());

【讨论】:

  • 您没有显示您的管道...关于聚合器?如果不这样做,则必须在任何 handleRpc 或 handleForm 之前处理多个 httpContent。
  • 抱歉,没有看到您的管道...您只是错过了聚合器...添加它,它应该可以解决您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-21
相关资源
最近更新 更多