最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang使用Gin框架實現(xiàn)http分塊傳輸

 更新時間:2023年05月16日 09:09:13   作者:Go學(xué)堂  
這篇文章主要為大家詳細(xì)介紹了Golang中如何使用Gin框架實現(xiàn)http分塊傳輸功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,需要的可以參考一下

今天,跟大家聊聊gin框架中是如何實現(xiàn)分片輸出的。主要分以下4點:

  • 分片輸出的效果圖
  • gin實現(xiàn)分片傳輸代碼
  • http分片傳輸?shù)幕A(chǔ):transfer-encoding
  • gin實現(xiàn)分片傳輸原理

效果圖

首先看下分片輸出的效果圖:

gin分片傳輸實現(xiàn)代碼

上面的效果圖中,網(wǎng)頁中的內(nèi)容不斷的輸出。在gin中是主要是利用了Flush函數(shù)實現(xiàn)的。如下代碼:

package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/test_stream", func(c *gin.Context) {
		w := c.Writer
		header := w.Header()
		header.Set("Content-Type", "text/html")
		w.WriteHeader(http.StatusOK)
		w.Write([]byte(`
			<html>
					<body>
		`))
		w.(http.Flusher).Flush()

        // 這里對每次循環(huán)輸出都進(jìn)行Flush刷新輸出
		for i := 0; i < 10; i++ {
			w.Write([]byte(fmt.Sprintf(`
				<h3>%d</h3>
			`, i)))
			//w.Flush()
			w.(http.Flusher).Flush()
			time.Sleep(time.Duration(1)*time.Second)
		}
        
		w.Write([]byte(`
			
					</body>
			</html>
		`))
		w.(http.Flusher).Flush()
	})

	r.Run("127.0.0.1:8080")
}

這里主要就是利用了第22行中的w.(http.Flusher).Flush()。 這里的Flush本質(zhì)上就是將Write的內(nèi)容立即輸出到客戶端的意思。

那么,為什么通過Flush就能實現(xiàn)上述效果呢?

分塊傳輸?shù)幕A(chǔ):http的 transfer-encoding:chunked 協(xié)議

分塊傳輸?shù)幕A(chǔ)就是http中的transfer-encoding:chunked協(xié)議。在http響應(yīng)報文中用頭字段“Transfer-Encoding: chunked”,表示響應(yīng)中的body不是一次性發(fā)送完畢,而是分成了許多的塊(chunk)逐個發(fā)送,直到發(fā)送完畢。

分塊傳輸?shù)木幋a規(guī)則如下: 1)每個分塊包含兩個部分,<長度頭>和&<數(shù)據(jù)塊> 2) <長度頭>是以 CRLF(回車換行,即\r\n)結(jié)尾的一行明文,用 16 進(jìn)制數(shù)字表示長度 3) <數(shù)據(jù)塊>緊跟在<長度頭>后,最后也用 CRLF 結(jié)尾,但數(shù)據(jù)不包含 CRLF 4)最后用一個長度為 0 的塊表示數(shù)據(jù)傳輸結(jié)束,即“0\r\n\r\n”。

為什么通過Flush函數(shù)就能實現(xiàn)分塊傳輸

到了本篇的核心部分了,為什么在gin中通過Flush函數(shù)就能實現(xiàn)分塊傳輸了呢?首先,在gin框架中正常的輸出是通過Context.Writer.Write函數(shù)進(jìn)行輸出的。而Writer是net/http包中的response對象,該response對象包含了本次http的連接對象conn。以下是從Context.Writer對象到conn對象的一個層級關(guān)系,如下:

Context.Writer對象指向了response對象,response對象中包含一個緩沖的Writer對象w,w的底層輸出對象時chunkWriter對象cw,cw又指向了本次的http連接對象response.conn。

那么,基于這個層級結(jié)構(gòu),Context.Writer.Write的寫入過程如下:

我們簡化一些,就是Context.Writer.Write先將內(nèi)容寫入到緩沖區(qū)w中,然后等本次請求邏輯處理完畢,再調(diào)用緩存區(qū)w的Flush功能,將緩沖區(qū)w中的內(nèi)容寫入到cw中,然后調(diào)用cw的flush功能,這時就寫入了http的響應(yīng)頭Content-Length為寫入數(shù)據(jù)的長度,并且將內(nèi)容通過conn.bufw.flush輸出給客戶端。

簡化一下gin的輸出過程:內(nèi)容先寫入到緩沖區(qū),最后將緩沖區(qū)的內(nèi)容一次性全部輸出給客戶端。

劃重點,Content-Length頭部的輸出是和分塊傳輸?shù)闹饕獏^(qū)別。

接下來再看分塊輸出。

其實現(xiàn)的思想就是通過http的Transfer-Encoding: chunked頭告訴客戶端,服務(wù)端的內(nèi)容要分塊傳輸了。然后服務(wù)端就將內(nèi)容先寫入緩沖區(qū),然后立即使用Flush函數(shù)將緩沖區(qū)的內(nèi)容輸出到客戶端。這就是一個塊的輸出。然后依次循環(huán)寫入,F(xiàn)lush刷新輸出這個過程。

下圖是gin中分塊傳輸?shù)牧鞒虉D:

在分塊輸出的時候,在response.cw.flush階段,可以判定到該請求還未處理完畢(在net/http包中,本次請求處理完畢才會調(diào)用一個finishRequest的函數(shù)以標(biāo)識本次請求處理完畢),所以會自動寫入一個http的頭信息: Transfer-Encoding: chunked。當(dāng)客戶端收到該響應(yīng)時,檢測到header中的chunked,就表示本次響應(yīng)還未結(jié)束,會繼續(xù)接收后續(xù)的響應(yīng)內(nèi)容。

簡化一下gin的分塊傳輸流程如下:

總結(jié)

當(dāng)輸出內(nèi)容太大時,就可以使用分塊傳輸?shù)姆绞?。分塊傳輸是基于http的Transfer-Encoding: chunked協(xié)議進(jìn)行的。當(dāng)客戶端接收到該響應(yīng)頭時,就知道服務(wù)端的內(nèi)容還沒有傳輸完,不能關(guān)閉本次http連接。另一方面,gin框架通過Flush函數(shù)將緩沖區(qū)的內(nèi)容及時輸出來實現(xiàn)分塊傳輸。

到此這篇關(guān)于Golang使用Gin框架實現(xiàn)http分塊傳輸?shù)奈恼戮徒榻B到這了,更多相關(guān)Golang http分塊傳輸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解Golang中指針的用途與技巧

    深入理解Golang中指針的用途與技巧

    在 Go 語言中,指針是一種重要的概念,了解和正確使用指非常關(guān)鍵,因此本文小編就來和大家講講Golang 中指針的概念與用法,希望對大家有所幫助
    2023-05-05
  • GO 函數(shù)式選項模式(Functional Options Pattern)

    GO 函數(shù)式選項模式(Functional Options Pattern)

    Option模式支持傳遞多個參數(shù),并且在參數(shù)個數(shù)、類型發(fā)生變化時保持兼容性,任意順序傳遞參數(shù),下面給大家介紹GO 函數(shù)式選項模式(Functional Options Pattern)的相關(guān)知識,感興趣的朋友一起看看吧
    2021-10-10
  • GO語言ini配置文件的讀取的操作

    GO語言ini配置文件的讀取的操作

    這篇文章主要介紹了GO語言ini配置文件的讀取的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • 詳解Golang中Channel的原理和使用技巧

    詳解Golang中Channel的原理和使用技巧

    Channel管道提供了一種機(jī)制,它在兩個并發(fā)執(zhí)行的協(xié)程之間進(jìn)行同步,并通過傳遞與該管道元素類型相符的值來進(jìn)行通信。本文主要介紹了Channel的原理和使用技巧,需要的可以參考一下
    2022-11-11
  • golang并發(fā)編程中Goroutine 協(xié)程的實現(xiàn)

    golang并發(fā)編程中Goroutine 協(xié)程的實現(xiàn)

    Go語言中的協(xié)程是一種輕量級線程,通過在函數(shù)前加go關(guān)鍵字來并發(fā)執(zhí)行,具有動態(tài)棧、快速啟動和低內(nèi)存使用等特點,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-10-10
  • Go?Excelize?API源碼閱讀SetSheetViewOptions示例解析

    Go?Excelize?API源碼閱讀SetSheetViewOptions示例解析

    這篇文章主要為大家介紹了Go-Excelize?API源碼閱讀SetSheetViewOptions示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • golang flag包的使用教程

    golang flag包的使用教程

    golang 的 flag 包是用于處理命令行參數(shù)的工具包,我們可以基于這個包來開發(fā)自定義的命令行工具,下面小編就來為大家介紹一下flag包的具體使用吧
    2023-09-09
  • Go?1.21新內(nèi)置函數(shù)min、max和clear的用法詳解

    Go?1.21新內(nèi)置函數(shù)min、max和clear的用法詳解

    Go?1.21?版本已經(jīng)正式發(fā)布,它帶來了許多新特性和改進(jìn),其中引入了的三個新內(nèi)置函數(shù):max、min?和?clear,接下來我們就來看看這些函數(shù)的用途和特點吧
    2023-08-08
  • 簡單聊聊Go語言的注釋

    簡單聊聊Go語言的注釋

    這篇文章主要介紹了簡單聊聊Go語言的注釋的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • Go語言中實現(xiàn)Unix風(fēng)格的進(jìn)程管道方法實例

    Go語言中實現(xiàn)Unix風(fēng)格的進(jìn)程管道方法實例

    這篇文章主要為大家介紹了Go語言中實現(xiàn)Unix風(fēng)格的進(jìn)程管道方法實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12

最新評論

铁力市| 衡阳县| 郧西县| 福安市| 荣成市| 苏州市| 闽清县| 清徐县| 浦县| 和田县| 桓台县| 仲巴县| 武隆县| 沙田区| 越西县| 中西区| 黄冈市| 察雅县| 海伦市| 漳平市| 淮阳县| 合川市| 静海县| 四平市| 嘉鱼县| 津市市| 九龙县| 曲水县| 喀什市| 乌拉特前旗| 资阳市| 从化市| 乐陵市| 灌云县| 朝阳市| 满城县| 康平县| 延边| 繁昌县| 利津县| 溧阳市|