下面列出了怎么用 io.netty.handler.codec.http2.Http2FrameCodec 的API类实例代码及写法,或者点击链接到github查看源代码。
static void registerClose(Channel channel) {
ConnectionObserver owner = channel.attr(OWNER).get();
channel.closeFuture()
.addListener(f -> {
Channel parent = channel.parent();
Http2FrameCodec frameCodec = parent.pipeline().get(Http2FrameCodec.class);
int numActiveStreams = frameCodec.connection().local().numActiveStreams();
if (log.isDebugEnabled()) {
log.debug(format(channel, "Stream closed, now {} active streams, {} max active streams."),
numActiveStreams,
frameCodec.connection().local().maxActiveStreams());
}
if (numActiveStreams == 0) {
channel.attr(OWNER).set(null);
invalidate(owner, parent);
}
});
}
private void configureHttp2(ChannelPipeline pipeline) {
// setup the initial stream settings for the server to use.
Http2Settings settings = new Http2Settings()
.maxConcurrentStreams(maxConcurrentStreams)
.initialWindowSize(initialWindowSize)
.headerTableSize(maxHeaderTableSize)
.maxHeaderListSize(maxHeaderListSize);
Http2FrameCodec frameCodec = Http2FrameCodecBuilder.forServer()
.frameLogger(FRAME_LOGGER)
.initialSettings(settings)
.validateHeaders(true)
.build();
Http2MultiplexHandler multiplexHandler = new Http2MultiplexHandler(http2StreamHandler);
// The frame codec MUST be in the pipeline.
pipeline.addBefore("codec_placeholder", /* name= */ null, frameCodec);
pipeline.replace("codec_placeholder", HTTP_CODEC_HANDLER_NAME, multiplexHandler);
}
@Override
protected void initChannel(SocketChannel ch) {
Http2FrameCodec codec = Http2FrameCodecBuilder.forServer()
.autoAckPingFrame(true)
.initialSettings(new Http2Settings()
.initialWindowSize(16384)
.maxFrameSize(16384)
.maxConcurrentStreams(5))
.build();
ch.pipeline().addLast(codec);
ch.pipeline().addLast(handlerSupplier.get());
}
@Override
protected void initChannel(SocketChannel ch) {
Http2FrameCodec codec = Http2FrameCodecBuilder.forServer()
.initialSettings(new Http2Settings()
.maxConcurrentStreams(5))
.build();
ch.pipeline().addLast(codec);
ch.pipeline().addLast(handlerSupplier.get());
}
public static EmbeddedChannel newHttp2Channel(ChannelHandler channelHandler) {
Http2FrameCodec http2FrameCodec = Http2FrameCodecBuilder.forClient().initialSettings(
Http2Settings.defaultSettings().initialWindowSize(INITIAL_WINDOW_SIZE))
.frameLogger(new Http2FrameLogger(LogLevel.DEBUG)).build();
EmbeddedChannel channel = new EmbeddedChannel(http2FrameCodec,
new Http2MultiplexHandler(channelHandler));
channel.attr(ChannelAttributeKey.HTTP2_CONNECTION).set(http2FrameCodec.connection());
channel.attr(ChannelAttributeKey.HTTP2_INITIAL_WINDOW_SIZE).set(INITIAL_WINDOW_SIZE);
channel.attr(ChannelAttributeKey.PROTOCOL_FUTURE).set(CompletableFuture.completedFuture(Protocol.HTTP2));
return channel;
}
@Override
public void operationComplete(Future<Http2StreamChannel> future) {
Channel channel = pooledRef.poolable().channel();
Http2FrameCodec frameCodec = channel.pipeline().get(Http2FrameCodec.class);
if (future.isSuccess()) {
Http2StreamChannel ch = future.getNow();
if (!frameCodec.connection().local().canOpenStream()) {
if (!retried) {
if (log.isDebugEnabled()) {
log.debug(format(ch, "Immediately aborted pooled channel max active streams is reached, " +
"re-acquiring a new channel"));
}
pool.acquire(Duration.ofMillis(pendingAcquireTimeout))
.subscribe(new DisposableAcquire(this));
}
else {
sink.error(new IOException("Error while acquiring from " + pool + ". Max active streams is reached."));
}
}
else {
ChannelOperations<?, ?> ops = ChannelOperations.get(ch);
if (ops != null) {
obs.onStateChange(ops, STREAM_CONFIGURED);
sink.success(ops);
}
if (log.isDebugEnabled()) {
log.debug(format(ch, "Stream opened, now {} active streams, {} max active streams."),
frameCodec.connection().local().numActiveStreams(),
frameCodec.connection().local().maxActiveStreams());
}
}
}
else {
sink.error(future.cause());
}
release(this, channel);
}
static void configureHttp11OrH2CleartextPipeline(
ChannelPipeline p,
boolean acceptGzip,
HttpResponseDecoderSpec decoder,
Http2Settings http2Settings,
@Nullable Supplier<? extends ChannelMetricsRecorder> metricsRecorder,
ConnectionObserver observer,
ChannelOperations.OnSetup opsFactory,
@Nullable Function<String, String> uriTagValue) {
HttpClientCodec httpClientCodec =
new HttpClientCodec(
decoder.maxInitialLineLength(),
decoder.maxHeaderSize(),
decoder.maxChunkSize(),
decoder.failOnMissingResponse,
decoder.validateHeaders(),
decoder.initialBufferSize(),
decoder.parseHttpAfterConnectRequest);
Http2FrameCodecBuilder http2FrameCodecBuilder =
Http2FrameCodecBuilder.forClient()
.validateHeaders(decoder.validateHeaders())
.initialSettings(http2Settings);
if (p.get(NettyPipeline.LoggingHandler) != null) {
http2FrameCodecBuilder.frameLogger(new Http2FrameLogger(LogLevel.DEBUG,
"reactor.netty.http.client.h2"));
}
Http2FrameCodec http2FrameCodec = http2FrameCodecBuilder.build();
Http2ClientUpgradeCodec upgradeCodec = new Http2ClientUpgradeCodec(http2FrameCodec, new H2CleartextCodec(http2FrameCodec, opsFactory));
HttpClientUpgradeHandler upgradeHandler = new HttpClientUpgradeHandler(httpClientCodec, upgradeCodec, decoder.h2cMaxContentLength());
p.addBefore(NettyPipeline.ReactiveBridge, null, httpClientCodec)
.addBefore(NettyPipeline.ReactiveBridge, NettyPipeline.H2CUpgradeHandler, upgradeHandler)
.addBefore(NettyPipeline.ReactiveBridge, NettyPipeline.HttpTrafficHandler, new HttpTrafficHandler(observer));
if (acceptGzip) {
p.addAfter(NettyPipeline.HttpCodec, NettyPipeline.HttpDecompressor, new HttpContentDecompressor());
}
if (metricsRecorder != null) {
ChannelMetricsRecorder channelMetricsRecorder = metricsRecorder.get();
if (channelMetricsRecorder instanceof HttpClientMetricsRecorder) {
p.addBefore(NettyPipeline.ReactiveBridge,
NettyPipeline.HttpMetricsHandler,
new HttpClientMetricsHandler((HttpClientMetricsRecorder) channelMetricsRecorder, uriTagValue));
}
}
}
H2CleartextCodec(Http2FrameCodec http2FrameCodec, ChannelOperations.OnSetup opsFactory) {
this.http2FrameCodec = http2FrameCodec;
this.opsFactory = opsFactory;
}