例如,如果我想构建一个websocket服务器,我想知道应该在initChannel
方法中放置什么。然后我在netty的源代码中找到了websocket示例,我需要在其中执行以下操作:
public void initChannel(final SocketChannel ch) throws Exception {
ch.pipeline().addLast(
new HttpRequestDecoder(),
new HttpObjectAggregator(65536),
new HttpResponseEncoder(),
new WebSocketServerProtocolHandler("/websocket"),
new CustomTextFrameHandler());
}
但我不知道为什么我需要按照这样的顺序放置对象。在HttpObjectAggregator
的描述中,我发现了类似的内容:
Be aware that you need to have the {@link HttpResponseEncoder} or {@link HttpRequestEncoder} before the {@link HttpObjectAggregator} in the {@link ChannelPipeline}.
但是在上面的代码HttpObjectAggregator
中,对象位于HttpResponseEncoder
对象之前。我很迷惑。我如何知道我按正确顺序放置这些对象?
答案 0 :(得分:1)
TLDR;您应该将HttpServerCodec
放入init方法中,以保持简单。如果您选择使用聚合器,请在HttpObjectAggregator
之前执行此操作。
我非常确定在HttpObjectAggregator之前放置编码器的建议是一个错字。编码器只有出站处理程序,而HttpObjectAggregator只是入站处理程序,这意味着事件永远不会与它们相互作用;所以他们的相对秩序无关紧要。
这里需要注意的是HttpObjectAggregator会在某些情况下写出HttpObjects(主要是100 CONTINUE),并且要将HttpObject转换为可以在线路上发送的byte [],它需要一个HttpResponseEncoder才能在管道。在传出时,管道被反向遍历,因此编码器之前的编码器将接收聚合器发送的消息,但是编码器在它获胜之后。您发布的示例代码中有一个错误,只有在需要发送100 CONTINUE时才会触发该错误。看起来这个错误是通过在聚合器之前用HttpServerCodec替换编码器/解码器来修复的。
解码器,如HttpRequestDecoder或HttpResponseDecoder只是一个入站处理程序,它们需要在HttpObjectAggregator之前才能正常运行。这是因为这两个解码器将byte[]
转换为HttpObject
,而HttpObjectAggregator实际上是消息解码器,将HttpObject
转换为FullHttpMessage
。
Netty在一个类中引入了HttpServerCodec,它是HttpRequestDecoder和HttpResponseEncoder的组合。如果你把它放在你的聚合器之前,你将自己保存一行代码,并确保你的服务器有适当的编码器和解码器。
很好地参考了解邮件如何在入站和出站处理程序的管道中工作:https://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html
首次引入此措辞的问题(注意没有提及编码,只提及解码):https://github.com/netty/netty/issues/2401
将此措辞指出为错字/错误的问题:https://github.com/netty/netty/issues/2471