http之Transfer-Encoding

我们知道http连接是应一答的模式,但是有一种场景是服务器端需要向客户端推送消息,客户端只需要消费消息就可以了。常用的是websocket或者轮询,现在学习了一种新的方式http 块传输。
下面是块传输的示意图。如果一个块是一个消息的话,我们可以理解成服务端在给客户端推送消息。客户端只需要消费消息就可以达到目的了,k8s的list-watch机制就是利用了这个功能点。

  1. 每个分块包含一个 16 进制的数据长度值和真实数据。

  2. 数据长度值独占一行,和真实数据通过 CRLF(\r\n) 分割。

  3. 数据长度值,不计算真实数据末尾的 CRLF,只计算当前传输块的数据长度。

  4. 最后通过一个数据长度值为 0 的分块,来标记当前内容实体传输结束。
    下面的数据长度可能有问题。目的只是为了模拟。
    服务端测试代码
    @RequestMapping("hello")
    public void hello(HttpServletResponse response) throws InterruptedException, IOException {
    response.addHeader("Transfer-Encoding","chunked");
    for (int i = 0; i < 5; i++) {
    String body = "aaaaa" + i;
    PrintWriter writer = response.getWriter();
    writer.write(body.getBytes().length + "");
    writer.write("\r\n");
    writer.write(body);
    writer.write("\r\n");
    writer.flush();
    System.out.println("第一个块");
    }
    response.getWriter().write(0);
    response.getWriter().write("\r\n");
    }
    客户端测试代码
    public static void main(String[] args) throws IOException {
    CloseableHttpClient httpClient = HttpClients.createDefault();
    HttpGet httpGet = new HttpGet("http://127.0.0.1:8080/hello");
    CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
    InputStream inputStream = httpResponse.getEntity().getContent();
    for (int i = 0; i < 1; i++) {
    byte[] b = new byte[5];
    inputStream.read(b);
    System.out.println("=====================================================");
    System.out.println(new String(b));
    }
    }

posted @ 2021-05-09 15:46  1209231105  阅读(272)  评论(0)    收藏  举报