Vert.x核心模块 HTTP客户端推送 (九【4】)

客户端推送

服务器推送是HTTP/2的一个新特性,此特性使得可以在单一客户端请求中可以并行发出多个响应。推送处理器可以被设置到请求上用来接收服务器推送的请求/响应。

HttpClientRequest request =client.get("/index.html", response -> {

  //Process index.html response

});

 // Set a push handler to be aware of anyresource pushed by the server

request.pushHandler(pushedRequest -> {

   // Aresource is pushed for this request

 System.out.println("Server pushed " + pushedRequest.path());

   // Setan handler for the response

 pushedRequest.handler(pushedResponse -> {

   System.out.println("The response for the pushed request");

  });

});

 // End the request

request.end();

如果客户不想再接收推送的请求,客户端可以重置流:

request.pushHandler(pushedRequest -> {

  if(pushedRequest.path().equals("/main.js")) {

   pushedRequest.reset();

  } else{

    //Handle it

  }

});

接收定制的HTTP/2帧

HTTP/2是HTTP请求/响应模型中的一多帧的帧协义。协议支持其他帧的发送与接收。为了接收定制帧,可以在请求上使用定制帧处理器(customFrameHandler),当每次定制帧到达时,此处理器将会被调用。例子如下:

response.customFrameHandler(frame -> {

  System.out.println("Received a frame type=" + frame.type() +

      " payload" +frame.payload().toString());

});

客户端启用压缩

http客户端一起支持的还有HTTP压缩。这表示客户端让远程Http服务器知道此客户端支持压缩,并能处理压缩的响应体。一个http服务器可以自由选择是用支持的压缩算法进行压缩,还是不压缩的方式发回响应体。所以这仅是一个http服务器忽视或使用的提示。为了告知http服务器客户端支持哪种压缩,客户端提供一个支持的压缩算法值作为Accept-Encoding头的值。多个压缩算法被支持的情况,Vert.x将会添加下列头:

Accept-Encoding: gzip, deflate

服务器将选择其中之一。你可以检查服务器是否通过查看响应中的Content-Encoding头压缩了响应体,并发回。

如果响应体通过gzip压缩,响应体将包含下列头:

Content-Encoding: gzip

在创建客户端时设置setTryUseCompression选项启用压缩。默认压缩是禁用的。

HTTP/1.x池化和长连接

Http长连接允许多个请求使用一个连接,在向同一个服务器发送多个请求,这样连接使用就会更有效。对于HTTP/1.x版本,http客户端支持池化连接在请求间重用连接。为了池化,使用setKeepAlive进行请求客户端设置。默认值为true.当KeepAlive启用。Vert.x将会在每个发送的请求中添加Connection:Keep-Alive头。当KeepAlive禁用时,Vert.x在每个发送的请求中添加Connection:Close头,通知服务器在完成响应后连接将会被关闭。对于每个服务器的的连池池的最大连接数通过调用setMaxPoolSize进行设置。在启用池化创建请求时,如果池中的连接数小于最大连接数设置时,Vert.x会创建一个新的连接,否则会将请求添加到等待队列。活动连接不会被客户端自动关闭。为了关闭活动连接,可以关系客户端实例。作为另一种关闭活动连接的选择是用setIdleTimeout设置空闲超时时间,在超时时间内,任何不被使用的连接都会被关闭。请注意空闲时间的单位是秒而不毫秒。

 HTTP/1.1管道内嵌

客户端也支持在同一个连接上进行请求内嵌。请求内嵌意思在前一个请求的响应返回前,s可以发送另外请求。管道内嵌不适用于所有请求。为了启用管道内嵌,可以使用setPipelining进行启用。默认pipe-lining是禁用的。在启用客道内嵌后,发送一个请求将不必待前一个响应返回。单一连接上管道内嵌的请求数能过setPipeliningLimit时行限制。这个选项定义了在等待响应时发送http请求的最大数目。这个限制确保了在同一服务器的所有连接上的http请求分布的公平性。

 HTTP/2多路复用

HTTP/2主张对一个服务器使用单一连接,默认的http客户端对每个服务器使用单一连接,同一服务器的所有流是多路复用同一个连接。如需要多个连接或者使用池化时,会用到setHttp2MaxPoolSize方法。在每个连接上限制复用流的数量是必须的,同时使用池代替单一连接,这种情况可以用setHttp2MultiplexingLimit。

HttpClientOptions clientOptions = newHttpClientOptions().

   setHttp2MultiplexingLimit(10).

   setHttp2MaxPoolSize(3);

 // Uses up to 3 connections and up to 10 streamsper connection

HttpClient client =vertx.createHttpClient(clientOptions);

单个连接的复用限制设置在客户端上,用于限制每个连接上流也的数量。如果使用SETTINGS_MAX_CONCURRENT_STREAMS 配置设成较低限制,有效值甚至更低。HTTP/2连接不会被客户端自动关闭。为了关闭连接,必须调用客户端实例上的close方法。另一方法是用setIdleTimeout方法设置超时时间-一些在超时时间内不用的连接都将被关闭。请注意超时时间单位是秒而不是毫秒。

 HTTP连接

HttpConnection提供了处理HTTP连接事件,生命周期和设置的API。HTTP/2完整实现了HttpConnection的API。HTTP/1.x部分实现了HttpConnection的API:仅是关闭操作,关闭处理器,异常处理器被实现。此协议不提供其他操作的语义。

 服务器选项

connection方法反回一个服务器上的请求连接:

HttpConnection connection =request.connection();

在服务器上注册连接处理器获取进行连接时的通知

HttpServer server =vertx.createHttpServer(http2Options);

 server.connectionHandler(connection -> {

 System.out.println("A client connected");

});

 客户端连接

connection方法返回一个客户端连接:

HttpConnection connection =request.connection();

可以在请求上设置连接处理器获取连接通知

request.connectionHandler(connection -> {

 System.out.println("Connected to the server");

});

 连接设置

HTTP/2使用Http2Settiongs数据对象进行配置。每个端点必须遵守连接另一端发送的配置。在连接建立时,客户端与服务器交换初始设置。使用setInitialSettiongs进行初始设置客户端和服务器。连接建立后,可以在任何时候进行设置:

connection.updateSettings(newHttp2Settings().setMaxConcurrentStreams(100));

在远程端应该确认收到设置更新,可以设置回调确认收到通知:

connection.updateSettings(newHttp2Settings().setMaxConcurrentStreams(100), ar -> {

  if(ar.succeeded()) {

   System.out.println("The settings update has been acknowledged");

  }

});

相反 remoteSettingsHandler在收到远程设置时被调用并获得通知:

connection.remoteSettingsHandler(settings ->{

 System.out.println("Received new settings");

});

注释:这仅适用于HTTP/2协议

 连接心跳

HTTP/2连接ping在判断连接来回耗时,检查连接有效性上是有用的:ping发送PIBG帧到远程点。

Buffer data = Buffer.buffer();

for (byte i = 0;i < 8;i++) {

 data.appendByte(i);

}

connection.ping(data, pong -> {

 System.out.println("Remote side replied");

});

在一个PING帧收到之后,Vert.x会自动发送一个确认,使用一个处理器可以处理收到ping的通知:

connection.pingHandler(ping -> {

 System.out.println("Got pinged by remote side");

});

处理器会适时被通知,无论确认都会被发回。此特性是针对HTTP/2协义进行的实现。

注意:仅适用于HTTP/2协议。

 连接关闭和停止

 调用shutdown方法将会发送GOAWAY帧到连接的远程端。请求对方停止创建流:客户端将会停止新建请求并且服务器将停止推送响应。在GOAWAY帖发送之后,连接等待一些时间(默认30秒)直到当前所有流关闭然后关闭连接:
connection.shutdown();

在所有流关闭后,shutdownHandler通知还没有关闭的连接。也有只发送GOAWAY帧的可能,与shutdown的主要区别是,GOAWAY仅告知连接的远程端停止创建新的流还没有流关闭的计划:

connection.goAway(0);

相反,在收到GOAWAY帧时也能被通知:

connection.goAwayHandler(goAway -> {

 System.out.println("Received a go away frame");

});

shutdownHandler在当前流关闭和连接关闭时会被调用:

connection.goAway(0);

connection.shutdownHandler(v -> {

   // Allstreams are closed, close the connection

 connection.close();

});

也适用于在收到GOAWAY帧时。

注意:仅适用于HTTP/2协议

 连接关闭

连接的close方法半闭连接:

·          close方法半闭HTTP/1.x的socket

·          HTTP/2立既关闭,在连接关闭前,GOAWAY帧仍将会发送

在连接被关闭时调用closeHandler。

你可能感兴趣的:(Vert.x)