Golang gin framework for block transmission

1) Overview: block transmission

This is a "division into zero" or "divide and conquer" mentality, which is embodied in the HTTP protocol as "chunked" transfer coding. In the HTTP response message, the header field "Transfer-Encoding: chunked" is used to indicate that the body in the response is not sent all at once, but is divided into many chunks and sent one by one until the sending is completed.

2) Coding rules for block transmission

1) Each block contains two parts, <length header> and <data block>;
2) <length header> is a line of plain text ending with CRLF (carriage return, line feed, ie \r\n), in hexadecimal The number indicates the length;
3) <data block> immediately after the <length header>, and finally ends with CRLF, but the data does not contain CRLF;
4) Finally, a block with a length of 0 is used to indicate the end of data transmission, that is, "0\ r\n\r\n".
Insert picture description here

3) golang code

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) Browser test

It can be found that the browser interface gradually receives 0, 1, 2, 3....
Note: The message seen from the browser is not a complete message, because it is processed by the browser, and the <length header> information of the block is removed.
Insert picture description hereInsert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/nangonghen/article/details/107707725