如何决定Netty通道管道中的操作顺序

new*_*guy 0 pipeline websocket netty

例如,如果我想构建一个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());
            }
Run Code Online (Sandbox Code Playgroud)

但我不知道为什么需要按这样的顺序放置对象。在描述中HttpObjectAggregator我发现了这样的内容:

Be aware that you need to have the {@link HttpResponseEncoder} or {@link HttpRequestEncoder} before the {@link HttpObjectAggregator} in the {@link ChannelPipeline}.

但在上面的代码中,HttpObjectAggregator对象位于HttpResponseEncoder对象之前。我很困惑。我怎么知道我正在以正确的顺序放置这些对象?

Chr*_*ole 5

太长了;HttpServerCodec为了保持简单,您应该将其放入init 方法中。HttpObjectAggregator如果您选择使用聚合器,请先执行此操作。

我非常确定关于将编码器放在 HttpObjectAggregator 之前的建议是一个拼写错误。编码器是仅出站处理程序,而 HttpObjectAggregator 是仅入站处理程序,这意味着事件永远不会与它们两者交互;所以它们的相对顺序很重要是没有意义的。

这里需要注意的是,在某些情况下,HttpObjectAggregator 会写出 HttpObject(主要是 100 CONTINUE),并且为了将该 HttpObject 转换为可以在线发送的 byte[],它在管道中之前需要一个 HttpResponseEncoder。在传出时,管道是反向遍历的,因此前面的编码器将收到聚合器发送的消息,但后面的编码器不会。您发布的示例代码中有一个错误,只有在需要发送 100 CONTINUE 时才会出现该错误。看起来这个错误是通过在聚合器之前用 HttpServerCodec 替换编码器/解码器来修复的。

解码器(例如 HttpRequestDecoder 或 HttpResponseDecoder)是仅入站处理程序,它们需要位于 HttpObjectAggregator 之前才能正常运行。这是因为这两个解码器将 a 转换byte[]为 a HttpObject,而 HttpObjectAggregator 实际上是一个将 a 转换HttpObject为 a的消息到消息解码器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