Netty HTTP服务器响应

3
这可能很简单,但我无法解决。我的基于Netty 4的http服务器导致http客户端在响应期间挂起。它成功发送其响应有效负载(使用curl作为客户端进行观察),但客户端似乎没有意识到响应已经完成,它们无限期地等待它完成。这是在curl、firefox和chrome中观察到的。
只有当我修改代码以关闭通道(channel.close,如下所示),然后客户端才确认响应已完成。否则,他们将继续等待它完成。我希望通道保持打开状态,以便下一个客户端请求不需要打开新连接(我希望具有持续连接的行为),因此关闭通道似乎不可行。因此,我不确定服务器应该如何标记响应已结束 - 而不关闭连接。
服务器代码:
val response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK)
val buf = new StringBuilder
buf.append("hello")
response.data.writeBytes(Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8))
ctx.write(response).addListener(new ChannelFutureListener(){
  def operationComplete(channelFuture: ChannelFuture){
    if (channelFuture.isSuccess){
        println("server write finished successfully")
        //channelFuture.channel.close <===== if uncommented, clients receive the response, otherwise they just keep waiting forever
    }
    else 
        println ("server write failed: " + channelFuture.cause + "\n" + channelFuture.cause.getStackTraceString)
  }
})  

我错过了什么?

你是否发送了Content-Length头? - Kylar
不用,我没有主动添加任何标题。我需要添加吗? - matanster
1
是的。如果没有Content-Length头,您的客户端不知道何时停止读取。如果您的内容只是“hello”,那么请添加:Content-Length: 5。 - Kylar
谢谢。我有点天真地认为writeBytes会处理这个问题...难道没有其他使用Netty API来组合响应数据并同时处理内容和长度的方法吗?在API中,响应数据的长度不是在某个地方透明地管理吗?我对Netty还很陌生。 - matanster
不,没有。我有辅助类来完成它,但这是你需要自己处理的事情。 - Kylar
非常感谢。您是否愿意把这个转化为答案,这样我就可以将它标记为您的回答了?如果您不介意的话,我会自己回答这个问题来结束它。离题一点:我可能会追求除了netty + http以外的其他服务器方式,因为如果有任何迹象表明我不想为实现明显结果而进行低级编程。 - matanster
1个回答

2
您需要添加Content-Length标头,否则客户端将不知道何时停止读取,并持续轮询获取更多数据。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接