下面列出了怎么用 io.netty.handler.codec.http2.Http2Settings 的API类实例代码及写法,或者点击链接到github查看源代码。
public void updateWindow() throws Http2Exception {
if (!autoTuneFlowControlOn) {
return;
}
pingReturn++;
long elapsedTime = (System.nanoTime() - lastPingTime);
if (elapsedTime == 0) {
elapsedTime = 1;
}
long bandwidth = (getDataSincePing() * TimeUnit.SECONDS.toNanos(1)) / elapsedTime;
Http2LocalFlowController fc = decoder().flowController();
// Calculate new window size by doubling the observed BDP, but cap at max window
int targetWindow = Math.min(getDataSincePing() * 2, MAX_WINDOW_SIZE);
setPinging(false);
int currentWindow = fc.initialWindowSize(connection().connectionStream());
if (targetWindow > currentWindow && bandwidth > lastBandwidth) {
lastBandwidth = bandwidth;
int increase = targetWindow - currentWindow;
fc.incrementWindowSize(connection().connectionStream(), increase);
fc.initialWindowSize(targetWindow);
Http2Settings settings = new Http2Settings();
settings.initialWindowSize(targetWindow);
frameWriter().writeSettings(ctx(), settings, ctx().newPromise());
}
}
public void updateWindow() throws Http2Exception {
if (!autoTuneFlowControlOn) {
return;
}
pingReturn++;
long elapsedTime = (System.nanoTime() - lastPingTime);
if (elapsedTime == 0) {
elapsedTime = 1;
}
long bandwidth = (getDataSincePing() * TimeUnit.SECONDS.toNanos(1)) / elapsedTime;
Http2LocalFlowController fc = decoder().flowController();
// Calculate new window size by doubling the observed BDP, but cap at max window
int targetWindow = Math.min(getDataSincePing() * 2, MAX_WINDOW_SIZE);
setPinging(false);
int currentWindow = fc.initialWindowSize(connection().connectionStream());
if (targetWindow > currentWindow && bandwidth > lastBandwidth) {
lastBandwidth = bandwidth;
int increase = targetWindow - currentWindow;
fc.incrementWindowSize(connection().connectionStream(), increase);
fc.initialWindowSize(targetWindow);
Http2Settings settings = new Http2Settings();
settings.initialWindowSize(targetWindow);
frameWriter().writeSettings(ctx(), settings, ctx().newPromise());
}
}
@Override
protected void manualSetUp() throws Exception {
assertNull("manualSetUp should not run more than once", handler());
initChannel(new GrpcHttp2ServerHeadersDecoder(GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE));
// replace the keepAliveManager with spyKeepAliveManager
spyKeepAliveManager =
mock(KeepAliveManager.class, delegatesTo(handler().getKeepAliveManagerForTest()));
handler().setKeepAliveManagerForTest(spyKeepAliveManager);
// Simulate receipt of the connection preface
handler().handleProtocolNegotiationCompleted(Attributes.EMPTY, /*securityInfo=*/ null);
channelRead(Http2CodecUtil.connectionPrefaceBuf());
// Simulate receipt of initial remote settings.
ByteBuf serializedSettings = serializeSettings(new Http2Settings());
channelRead(serializedSettings);
}
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);
}
static void configureHttp2Pipeline(ChannelPipeline p, HttpResponseDecoderSpec decoder, Http2Settings http2Settings,
ConnectionObserver observer) {
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"));
}
p.addBefore(NettyPipeline.ReactiveBridge, NettyPipeline.HttpCodec, http2FrameCodecBuilder.build())
.addBefore(NettyPipeline.ReactiveBridge, NettyPipeline.H2MultiplexHandler, new Http2MultiplexHandler(new H2Codec()))
.addBefore(NettyPipeline.ReactiveBridge, NettyPipeline.HttpTrafficHandler, new HttpTrafficHandler(observer));
}
static void configureH2Pipeline(ChannelPipeline p,
ServerCookieDecoder cookieDecoder,
ServerCookieEncoder cookieEncoder,
boolean forwarded,
Http2Settings http2Settings,
ConnectionObserver listener,
ChannelOperations.OnSetup opsFactory,
boolean validate) {
p.remove(NettyPipeline.ReactiveBridge);
Http2FrameCodecBuilder http2FrameCodecBuilder =
Http2FrameCodecBuilder.forServer()
.validateHeaders(validate)
.initialSettings(http2Settings);
if (p.get(NettyPipeline.LoggingHandler) != null) {
http2FrameCodecBuilder.frameLogger(new Http2FrameLogger(LogLevel.DEBUG,
"reactor.netty.http.server.h2"));
}
p.addLast(NettyPipeline.HttpCodec, http2FrameCodecBuilder.build())
.addLast(NettyPipeline.H2MultiplexHandler,
new Http2MultiplexHandler(new H2Codec(opsFactory, listener, forwarded, cookieEncoder, cookieDecoder)));
}
Http11OrH2CleartextCodec(
ServerCookieDecoder cookieDecoder,
ServerCookieEncoder cookieEncoder,
boolean debug,
boolean forwarded,
Http2Settings http2Settings,
ConnectionObserver listener,
ChannelOperations.OnSetup opsFactory,
boolean validate) {
this.cookieDecoder = cookieDecoder;
this.cookieEncoder = cookieEncoder;
this.forwarded = forwarded;
Http2FrameCodecBuilder http2FrameCodecBuilder =
Http2FrameCodecBuilder.forServer()
.validateHeaders(validate)
.initialSettings(http2Settings);
if (debug) {
http2FrameCodecBuilder.frameLogger(new Http2FrameLogger(
LogLevel.DEBUG,
"reactor.netty.http.server.h2"));
}
this.http2FrameCodec = http2FrameCodecBuilder.build();
this.listener = listener;
this.opsFactory = opsFactory;
}
H2OrHttp11Codec(
@Nullable BiPredicate<HttpServerRequest, HttpServerResponse> compressPredicate,
ServerCookieDecoder cookieDecoder,
ServerCookieEncoder cookieEncoder,
HttpRequestDecoderSpec decoder,
boolean forwarded,
Http2Settings http2Settings,
ConnectionObserver listener,
@Nullable Supplier<? extends ChannelMetricsRecorder> metricsRecorder,
int minCompressionSize,
ChannelOperations.OnSetup opsFactory,
@Nullable Function<String, String> uriTagValue) {
super(ApplicationProtocolNames.HTTP_1_1);
this.compressPredicate = compressPredicate;
this.cookieDecoder = cookieDecoder;
this.cookieEncoder = cookieEncoder;
this.decoder = decoder;
this.forwarded = forwarded;
this.http2Settings = http2Settings;
this.listener = listener;
this.metricsRecorder = metricsRecorder;
this.minCompressionSize = minCompressionSize;
this.opsFactory = opsFactory;
this.uriTagValue = uriTagValue;
}
@Override
protected void manualSetUp() throws Exception {
assertNull("manualSetUp should not run more than once", handler());
initChannel(new GrpcHttp2ServerHeadersDecoder(GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE));
// replace the keepAliveManager with spyKeepAliveManager
spyKeepAliveManager =
mock(KeepAliveManager.class, delegatesTo(handler().getKeepAliveManagerForTest()));
handler().setKeepAliveManagerForTest(spyKeepAliveManager);
// Simulate receipt of the connection preface
handler().handleProtocolNegotiationCompleted(Attributes.EMPTY, /*securityInfo=*/ null);
channelRead(Http2CodecUtil.connectionPrefaceBuf());
// Simulate receipt of initial remote settings.
ByteBuf serializedSettings = serializeSettings(new Http2Settings());
channelRead(serializedSettings);
}
private Http2Settings http2Settings() {
final Http2Settings settings = new Http2Settings();
final int initialWindowSize = config.http2InitialStreamWindowSize();
if (initialWindowSize != Http2CodecUtil.DEFAULT_WINDOW_SIZE) {
settings.initialWindowSize(initialWindowSize);
}
final int maxFrameSize = config.http2MaxFrameSize();
if (maxFrameSize != Http2CodecUtil.DEFAULT_MAX_FRAME_SIZE) {
settings.maxFrameSize(maxFrameSize);
}
// Not using the value greater than 2^31-1 because some HTTP/2 client implementations use a signed
// 32-bit integer to represent an HTTP/2 SETTINGS parameter value.
settings.maxConcurrentStreams(Math.min(config.http2MaxStreamsPerConnection(), Integer.MAX_VALUE));
settings.maxHeaderListSize(config.http2MaxHeaderListSize());
return settings;
}
AbstractNettyHandler(
ChannelPromise channelUnused,
Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder,
Http2Settings initialSettings,
boolean autoFlowControl) {
super(channelUnused, decoder, encoder, initialSettings);
// During a graceful shutdown, wait until all streams are closed.
gracefulShutdownTimeoutMillis(GRACEFUL_SHUTDOWN_NO_TIMEOUT);
// Extract the connection window from the settings if it was set.
this.initialConnectionWindow = initialSettings.initialWindowSize() == null ? -1 :
initialSettings.initialWindowSize();
this.autoTuneFlowControlOn = autoFlowControl;
if (encoder instanceof ListeningEncoder) {
((ListeningEncoder) encoder).setListener(pingCountingListener);
}
}
@Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) {
if (firstSettings) {
firstSettings = false;
lifecycleManager.notifyReady();
}
}
@Override
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) {
if (firstSettings) {
firstSettings = false;
lifecycleManager.notifyReady();
}
}
AbstractNettyHandler(
ChannelPromise channelUnused,
Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
super(channelUnused, decoder, encoder, initialSettings);
// During a graceful shutdown, wait until all streams are closed.
gracefulShutdownTimeoutMillis(GRACEFUL_SHUTDOWN_NO_TIMEOUT);
// Extract the connection window from the settings if it was set.
this.initialConnectionWindow = initialSettings.initialWindowSize() == null ? -1 :
initialSettings.initialWindowSize();
}
@Test
public void transportReadyDelayedUntilConnectionPreface() throws Exception {
initChannel(new GrpcHttp2ServerHeadersDecoder(GrpcUtil.DEFAULT_MAX_HEADER_LIST_SIZE));
handler().handleProtocolNegotiationCompleted(Attributes.EMPTY, /*securityInfo=*/ null);
verify(transportListener, never()).transportReady(any(Attributes.class));
// Simulate receipt of the connection preface
channelRead(Http2CodecUtil.connectionPrefaceBuf());
channelRead(serializeSettings(new Http2Settings()));
verify(transportListener).transportReady(any(Attributes.class));
}
@Test
public void shouldAdvertiseMaxConcurrentStreams() throws Exception {
maxConcurrentStreams = 314;
manualSetUp();
ArgumentCaptor<Http2Settings> captor = ArgumentCaptor.forClass(Http2Settings.class);
verifyWrite().writeSettings(
any(ChannelHandlerContext.class), captor.capture(), any(ChannelPromise.class));
assertEquals(maxConcurrentStreams, captor.getValue().maxConcurrentStreams().intValue());
}
@Test
public void shouldAdvertiseMaxHeaderListSize() throws Exception {
maxHeaderListSize = 123;
manualSetUp();
ArgumentCaptor<Http2Settings> captor = ArgumentCaptor.forClass(Http2Settings.class);
verifyWrite().writeSettings(
any(ChannelHandlerContext.class), captor.capture(), any(ChannelPromise.class));
assertEquals(maxHeaderListSize, captor.getValue().maxHeaderListSize().intValue());
}
private CapturingGrpcHttp2ConnectionHandler capturingGrpcHandler() {
// Netty Boilerplate. We don't really need any of this, but there is a tight coupling
// between a Http2ConnectionHandler and its dependencies.
Http2Connection connection = new DefaultHttp2Connection(true);
Http2FrameWriter frameWriter = new DefaultHttp2FrameWriter();
Http2FrameReader frameReader = new DefaultHttp2FrameReader(false);
DefaultHttp2ConnectionEncoder encoder =
new DefaultHttp2ConnectionEncoder(connection, frameWriter);
DefaultHttp2ConnectionDecoder decoder =
new DefaultHttp2ConnectionDecoder(connection, encoder, frameReader);
return new CapturingGrpcHttp2ConnectionHandler(decoder, encoder, new Http2Settings());
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Http2Settings msg) throws Exception {
promise.setSuccess();
// Only care about the first settings message
ctx.pipeline().remove(this);
}
@Override
protected HelloWorldHttp2Handler build(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
HelloWorldHttp2Handler handler = new HelloWorldHttp2Handler(decoder, encoder, initialSettings);
frameListener(handler);
return handler;
}
@Override
public void channelCreated(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
SslHandler sslHandler = new SslHandler(sslFactory.createSSLEngine(host, port, SSLFactory.Mode.CLIENT));
pipeline.addLast(sslHandler);
pipeline.addLast(Http2FrameCodecBuilder.forClient()
.initialSettings(Http2Settings.defaultSettings()
.maxFrameSize(http2ClientConfig.http2FrameMaxSize)
.initialWindowSize(http2ClientConfig.http2InitialWindowSize))
.frameLogger(new Http2FrameLogger(LogLevel.DEBUG, "client"))
.build());
pipeline.addLast(new Http2MultiplexHandler(new ChannelInboundHandlerAdapter()));
}
@Override
protected Http2Handler build(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
Http2Handler handler = new Http2Handler(decoder, encoder, initialSettings);
frameListener(handler);
return handler;
}
@Test
public void shouldAdvertiseMaxConcurrentStreams() throws Exception {
maxConcurrentStreams = 314;
manualSetUp();
ArgumentCaptor<Http2Settings> captor = ArgumentCaptor.forClass(Http2Settings.class);
verifyWrite().writeSettings(
any(ChannelHandlerContext.class), captor.capture(), any(ChannelPromise.class));
assertEquals(maxConcurrentStreams, captor.getValue().maxConcurrentStreams().intValue());
}
@Override
protected Http2ServerChannelHandler build(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
Http2ServerChannelHandler handler = new Http2ServerChannelHandler(serverHandler, decoder, encoder,
initialSettings);
frameListener(handler);
return handler;
}
@Override
protected Http2ConnectionHandler build(
Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
// TODO(jkinkead): Set MAX_CONCURRENT_STREAMS value to something from config.
decoder.frameListener(new Http2Handler(encoder, maxPayloadBytes, corsHandler));
return new ConnectionHandler(decoder, encoder, initialSettings);
}
@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;
}
private Http2SettingsFrame http2SettingsFrame(long serverMaxStreams) {
return new Http2SettingsFrame() {
@Override
public Http2Settings settings() {
Http2Settings http2Settings = new Http2Settings();
http2Settings.maxConcurrentStreams(serverMaxStreams);
return http2Settings;
}
@Override
public String name() {
return "test";
}
};
}
FakeGrpcHttp2ConnectionHandler(ChannelPromise channelUnused,
Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder,
Http2Settings initialSettings,
boolean noop) {
super(channelUnused, decoder, encoder, initialSettings);
this.noop = noop;
}