golang gin框架进行分块传输

1)概述:分块传输

这是一种"化整为零"或"分治"的思路,在 HTTP 协议里的体现就是"chunked"分块传输编码。在http响应报文中用头字段“Transfer-Encoding: chunked”,表示响应中的body不是一次性发送完毕,而是分成了许多的块(chunk)逐个发送,直到发送完毕。

2)分块传输的编码规则

1)每个分块包含两个部分,<长度头>和<数据块>;
2)<长度头>是以 CRLF(回车换行,即\r\n)结尾的一行明文,用 16 进制数字表示长度;
3)<数据块>紧跟在<长度头>后,最后也用 CRLF 结尾,但数据不包含 CRLF;
4)最后用一个长度为 0 的块表示数据传输结束,即“0\r\n\r\n”。
在这里插入图片描述

3)golang代码

package main

import (
    "fmt"
    "github.com/gin-gonic/gin"
    "net/http"
    "time"
)

func main() {
    server := &APIServer{
        engine: gin.Default(),
    }
    server.registryApi()
    server.engine.Run(":38080")
}

type APIServer struct {
    engine *gin.Engine
}

func (s *APIServer) registryApi() {
    registryStream(s.engine)
}

func registryStream(engine *gin.Engine) {
    engine.GET("/stream", func(ctx *gin.Context) {
        w := ctx.Writer
        header := w.Header()
        //在响应头添加分块传输的头字段Transfer-Encoding: chunked
        header.Set("Transfer-Encoding", "chunked")
        header.Set("Content-Type", "text/html")
        w.WriteHeader(http.StatusOK)
      
        //Flush()方法,好比服务端在往一个文件中写了数据,浏览器会看见此文件的内容在不断地增加。
        w.Write([]byte(`
            <html>
                    <body>
        `))
        w.(http.Flusher).Flush()


        for i:=0 ;i<10; i++{
            w.Write([]byte(fmt.Sprintf(`
                <h1>%d</h1>
            `,i)))
            w.(http.Flusher).Flush()
            time.Sleep(time.Duration(1) * time.Second)
        }

        w.Write([]byte(`
                    </body>
            </html>
        `))
        w.(http.Flusher).Flush()
    })
}

4)浏览器测试

可以发现浏览器界面逐渐收到0,1,2,3…。
说明:从浏览器中看见的,不是完整的报文,因为是经过浏览器处理的,去掉了块的<长度头>信息。
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/nangonghen/article/details/107707725