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());
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());