我们有一个java服务器应用程序,正在侦听端口5545以进行http通信。
另一方面是C#Client应用程序,它将请求发送到服务器。
在发生代理问题之前,我们的通信基于TCP / IP。
现在我们想通过http切换到通信,但是我们在c#端遇到了一些奇怪的行为。
问题基于PostAsync Method
我们的Java Server正在使用Spring的Netty 4 Framework。当c#客户端发布数据时,我可以看到netty日志中的所有内容。 现在在java服务器发回响应的部分,c#方法就像死锁一样。
我发送响应的java方法是
private boolean writeResponse(boolean isSuccessful, String message, ChannelHandlerContext ctx) {
boolean keepAlive = HttpHeaders.isKeepAlive(_httpRequest);
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
isSuccessful ? HttpResponseStatus.OK : HttpResponseStatus.BAD_REQUEST,
Unpooled.copiedBuffer(message, CharsetUtil.UTF_8));
response.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "application/octet-stream; charset=UTF-8");
if (keepAlive) {
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, message.length());
response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
}
ctx.write(response);
return keepAlive;
}
c#客户端代码是
HttpClientHandler httpClientHandler = new HttpClientHandler();
client = new System.Net.Http.HttpClient(httpClientHandler) { BaseAddress = uri };
byte[] bytes = ...
ByteArrayContent byteContent = new ByteArrayContent(bytes);
var response = await client.PostAsync(uri, byteContent, tokenSource.Token);
当我添加ctx.channel().writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
时
在最后一次写入后的java端。 PostAsync方法获得响应,否则它只是卡住了,尽管java服务器已经发送了响应。
所以我的问题是,这是一种正常行为,还是有人可以解释我,我们做错了什么?
答案 0 :(得分:1)
每次都应该设置CONTENT_LENGTH,而不仅仅是当keepAlive为真时。
[编辑] 否则,客户端不知道是否以及何时完全接收到响应内容,并且后方法将不会返回。