netty 服务器收到两个 http 内容,但它们应该合并为一个

netty server receive two http content but they are should combine to one

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 

以上是日志。从Log中可以看出,客户端发送的seqNo都是497,而且确实发送了一次。但是从netty搭建的Server上,我们收到了两个http内容。因此,它们的长度都与header中的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 server,实现很简单,但是从日志中,我们看到有线的东西。感谢帮助

如下,我已经使用http codec来处理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 }              

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

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

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

管道示例:

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