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".
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.