1) 개요 : 블록 전송
이것은 "0으로 분할"또는 "분할 및 정복"정신이며 HTTP 프로토콜에서 "청크"전송 코딩으로 구현됩니다. HTTP 응답 메시지에서 헤더 필드 "Transfer-Encoding : chunked"는 응답의 본문이 한꺼번에 전송되지 않고 여러 청크로 분할되어 전송이 완료 될 때까지 하나씩 전송됨을 나타내는 데 사용됩니다.
2) 블록 전송을위한 코딩 규칙
1) 각 블록에는 <길이 헤더>와 <데이터 블록>의 두 부분이 포함됩니다
.2) <길이 헤더>는 16 진수로 된 CRLF (캐리지 리턴, 줄 바꿈, 즉 \ r \ n)로 끝나는 일반 텍스트 행입니다. 숫자는 길이를 나타냅니다
.3) <길이 헤더> 바로 뒤의 <데이터 블록>, 마지막으로 CRLF로 끝나지만 데이터에 CRLF가 포함되어 있지 않습니다
.4) 마지막으로 길이가 0 인 블록을 사용하여 끝을 나타냅니다. 즉, "0 \ r \ n \ r \ n"입니다.
3) 골랑 코드
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을 수신하는 것을 알 수 있습니다 ....
참고 : 브라우저에서 표시되는 메시지는 브라우저에서 처리되고 블록의 <length header> 정보가 제거되므로 완전한 메시지가 아닙니다.