shiningstarpxx
shiningstarpxx

Reputation: 41

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. But from the Server built with netty, we received two http content. Therefore, both they length are not consistent with Content-Length in the header. But Two content length 9 + 20 = 29, is should be combined to one.

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. Thanks for help

as following, i already use http codec to deal with http protocol, which is provided in 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 }              

Upvotes: 0

Views: 1115

Answers (1)

Frederic Br&#233;gier
Frederic Br&#233;gier

Reputation: 2206

You should use HttpObjectAggregator in order to get multiple content (chunk) into one response or request. Of course, you should also use an http codec, client or server, depending on your side...

Edit: if you don't use the aggregator, you have to handle yourself the multiple chunks (httpContent).

In your case, it is probable that you got 2 chunks but try to handle the request before loading all chunks...

Example of pipeline:

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

Upvotes: 2

Related Questions