Netty 将 HTTP/1.1 管道转换为双 HTTP/2 HTTP/1.1

Netty convert HTTP/1.1 pipeline to dual HTTP/2 HTTP/1.1

我构建了一个简单的管道来使用 Netty 提供 HTTP/1.1 内容,我正在寻找如何将其转换为 HTTP/2。我看到各种 类 用于在帧之间进行转换和协商,但我不知道如何将它们 assemble 放入管道中。以下代码在 Kotlin 中。我遇到的主要问题是 ALPN 协商,以及双向正确转换帧。

val bootstrap = ServerBootstrap()
bootstrap.group(transport.bossGroup, transport.workerGroup)
    .channelFactory(transport.factory)
    .childHandler(object : ChannelInitializer<SocketChannel>() {
        public override fun initChannel(ch: SocketChannel) {
            ch.pipeline().addLast("ssl", sslContext.newHandler(ch.alloc()))

            ch.pipeline().addLast("codec", HttpServerCodec())
            ch.pipeline().addLast("keepAlive", HttpServerKeepAliveHandler())
            ch.pipeline().addLast("aggregator", HttpObjectAggregator(65536))

            ch.pipeline().addLast("burstLimiter", burstLimiter)

            ch.pipeline().addLast(
                "readTimeoutHandler",
                ReadTimeoutHandler(60)
            )
            ch.pipeline().addLast(
                "writeTimeoutHandler",
                WriteTimeoutHandler(60)
            )

            ch.pipeline().addLast("streamer", ChunkedWriteHandler())
            ch.pipeline().addLast("handler", CustomHandler(httpHandler))
        }
    })

非代码解决方案怎么样 - 例如使用 Apache 的前端 netty - 让 Apache 为您做 HTTP/2?然后将流量传递给您的管道 see the Apache HTTP2 How To

我认为最简单的解决方案是同时使用 Http2MultiplexHandlerHttp2StreamFrameToHttpObjectCodec。这将允许您使用 HTTP2,同时仍然在您的处理程序中为您提供与 HTTP1 相同的“对象”。

所以它会是这样的:

ch.pipeline().addLast(Http2FrameCodecBuilder.forServer().build());
ch.pipeline().addLast(new Http2MultiplexHandler(new ChannelInitializer<Channel>() {
    @Override
    protected void initChannel(Channel ch) {
        ch.pipeline().addLast(new Http2StreamFrameToHttpObjectCodec(true));
        // Add all your other handlers that act on HTTP1 objects
    }
});

是否还需要为 SSL 等添加处理程序取决于您的用例。

有关更详细的示例,您还可以参考作为 netty 本身一部分的 http2 多路复用示例。根据客户的要求,它们同时处理 H1/H2。