如何决定 Netty 通道管道中的动作顺序
How to decide the sequence of actions in Netty channel pipeline
比如我想搭建一个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
对象之前。我很迷惑。我怎么知道我是否以正确的顺序放置了这些对象?
TLDR;您应该将 HttpServerCodec
放入您的 init 方法中,以保持简单。如果您选择使用聚合器,请在 HttpObjectAggregator
之前执行此操作。
我很确定关于将编码器放在 HttpObjectAggregator 之前的建议是错字。编码器是 outbound 唯一的处理程序,而 HttpObjectAggregator 是 inbound 唯一的处理程序,这意味着事件永远不会与它们交互;所以他们的相对顺序很重要是没有意义的。
这里需要注意的是,在某些情况下,HttpObjectAggregator 会写出 HttpObjects(主要是 100 CONTINUE),并且要将 HttpObject 转换为可以在线发送的 byte[],它之前需要一个 HttpResponseEncoder在管线中。在传出管道时反向遍历,因此它之前的编码器将接收聚合器发送的消息,但它之后的编码器不会。您发布的示例代码中有一个错误,只有在需要发送 100 CONTINUE 时才会被命中。看起来通过在聚合器之前用 HttpServerCodec 替换 encoder/decoder 来修复该错误。
解码器,如 HttpRequestDecoder 或 HttpResponseDecoder 是一个 inbound 唯一的处理程序,它们需要在 HttpObjectAggregator 之前才能正常运行。这是因为这两个解码器将 byte[]
转换为 HttpObject
,而 HttpObjectAggregator 实际上是将 HttpObject
转换为 FullHttpMessage
的消息到消息解码器。
Netty 引入了 HttpServerCodec,它是 HttpRequestDecoder 和 HttpResponseEncoder 的组合 class。如果你把它放在你的聚合器之前,你将为自己节省一行代码,并确保你有适合你的服务器的编码器和解码器。
了解消息在入站和出站处理程序的管道中如何工作的很好参考:https://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html
首次引入此措辞的问题(注意未提及编码,仅提及解码):https://github.com/netty/netty/issues/2401
此措辞被指出为 typo/bug 的问题:https://github.com/netty/netty/issues/2471
比如我想搭建一个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
对象之前。我很迷惑。我怎么知道我是否以正确的顺序放置了这些对象?
TLDR;您应该将 HttpServerCodec
放入您的 init 方法中,以保持简单。如果您选择使用聚合器,请在 HttpObjectAggregator
之前执行此操作。
我很确定关于将编码器放在 HttpObjectAggregator 之前的建议是错字。编码器是 outbound 唯一的处理程序,而 HttpObjectAggregator 是 inbound 唯一的处理程序,这意味着事件永远不会与它们交互;所以他们的相对顺序很重要是没有意义的。
这里需要注意的是,在某些情况下,HttpObjectAggregator 会写出 HttpObjects(主要是 100 CONTINUE),并且要将 HttpObject 转换为可以在线发送的 byte[],它之前需要一个 HttpResponseEncoder在管线中。在传出管道时反向遍历,因此它之前的编码器将接收聚合器发送的消息,但它之后的编码器不会。您发布的示例代码中有一个错误,只有在需要发送 100 CONTINUE 时才会被命中。看起来通过在聚合器之前用 HttpServerCodec 替换 encoder/decoder 来修复该错误。
解码器,如 HttpRequestDecoder 或 HttpResponseDecoder 是一个 inbound 唯一的处理程序,它们需要在 HttpObjectAggregator 之前才能正常运行。这是因为这两个解码器将 byte[]
转换为 HttpObject
,而 HttpObjectAggregator 实际上是将 HttpObject
转换为 FullHttpMessage
的消息到消息解码器。
Netty 引入了 HttpServerCodec,它是 HttpRequestDecoder 和 HttpResponseEncoder 的组合 class。如果你把它放在你的聚合器之前,你将为自己节省一行代码,并确保你有适合你的服务器的编码器和解码器。
了解消息在入站和出站处理程序的管道中如何工作的很好参考:https://netty.io/4.0/api/io/netty/channel/ChannelPipeline.html
首次引入此措辞的问题(注意未提及编码,仅提及解码):https://github.com/netty/netty/issues/2401
此措辞被指出为 typo/bug 的问题:https://github.com/netty/netty/issues/2471