简体   繁体   English

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 

The above is the log. 以上是日志。 from the Log, we can see that the client send seqNo are both 497, and it did sent once. 从日志中,我们可以看到客户端发送的seqNo均为497,并且发送了一次。 But from the Server built with netty, we received two http content. 但是从使用netty构建的服务器中,我们收到了两个http内容。 Therefore, both they length are not consistent with Content-Length in the header. 因此,它们的长度都与标头中的Content-Length不一致。 But Two content length 9 + 20 = 29, is should be combined to one. 但是两个内容长度为9 + 20 = 29,应该组合为一个。

the following is my server handler code, anyone could help me ? 以下是我的服务器处理程序代码,有人可以帮助我吗?

 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   }                     

Basiclly, we use netty do implements a http rpc server, implement is very simple, but from the log, we see wired things. 基本上,我们使用netty做一个http rpc服务器的实现,实现非常简单,但是从日志中我们可以看到有线的东西。 Thanks for help 感谢帮助

as following, i already use http codec to deal with http protocol, which is provided in netty.*.http 如下所示,我已经使用http编解码器来处理netty。*。http中提供的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 }              

You should use HttpObjectAggregator in order to get multiple content (chunk) into one response or request. 您应该使用HttpObjectAggregator才能将多个内容(块)放入一个响应或请求中。 Of course, you should also use an http codec, client or server, depending on your side... 当然,您还应根据自己的情况使用http编解码器,客户端或服务器...

Edit: if you don't use the aggregator, you have to handle yourself the multiple chunks (httpContent). 编辑:如果不使用聚合器,则必须处理多个块(httpContent)。

In your case, it is probable that you got 2 chunks but try to handle the request before loading all chunks... 在您的情况下,很可能您有2个块,但是尝试在加载所有块之前处理请求...

Example of pipeline: 管道示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM