golang 流式讀取和發(fā)送使用場(chǎng)景示例
場(chǎng)景
- 部分大模型(如gpt)的流式讀取,可以增加用戶體驗(yàn)。
- gin框架的流式問(wèn)答,與前端交互。
使用方法
- 我在使用框架req 的時(shí)候,發(fā)現(xiàn)無(wú)法從resp.Body流式讀取數(shù)據(jù),只能完整讀出來(lái)
原因是框架自動(dòng)幫我們讀取了resp,導(dǎo)致我們無(wú)法讀取流式的消息。
正常我們獲取返回值應(yīng)該是這樣的:
resp := c.c.Post(url).SetQueryParam("key", c.key).SetBody(msg).Do(ctx) data := resp.String()
想要讀取流式可以這么做:
resp := c.c.DisableAutoReadResponse().Post(url).SetQueryParam("key", c.key).SetBody(msg).Do(ctx) defer resp.Body.Close() scanner := bufio.NewScanner(resp.Body) for scanner.Scan() { line := scanner.Text() if strings.Contains(line, "text") { fmt.Println(line) } }
- 現(xiàn)在我們知道了如何從外部讀取流式數(shù)據(jù),那么我們?nèi)绾卫脀eb框架發(fā)送流式數(shù)據(jù)呢?
以gin框架為例
可以使用func (c *Context) Stream(step func(w io.Writer) bool) bool
函數(shù)
==具體使用方法如下==(這里我用了自己的代碼做了演示):
如果前端有需求,需要加上Header
c.Header("Content-Type", "application/octet-stream")
用bufio緩沖區(qū)向前端寫數(shù)據(jù)
stop := c.Stream(func(w io.Writer) bool { bw := bufio.NewWriter(w) if len(r.Choices) != 0 { gptResult.Detail = &r gptResult.Id = r.ID gptResult.Role = openai.ChatMessageRoleAssistant gptResult.Text += r.Choices[0].Delta.Content // 流傳輸 marshal, _ := json.Marshal(gptResult) if _, err := fmt.Fprintf(bw, "%s\n", marshal); err != nil { fmt.Println(err) return true } bw.Flush() } return false }) //stop if stop { fmt.Println("stop") break }
順便講一下flush吧,按官方文檔來(lái)說(shuō),是為了將寫好的數(shù)據(jù)發(fā)送給客戶端。
// The Flusher interface is implemented by ResponseWriters that allow // an HTTP handler to flush buffered data to the client. type Flusher interface { // Flush sends any buffered data to the client. Flush() }
以上就是golang流式讀取和發(fā)送的詳細(xì)內(nèi)容,更多關(guān)于golang流式讀取和發(fā)送的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
深入理解Golang?Channel?的底層結(jié)構(gòu)
這篇文章主要介紹了深入理解Golang?Channel?的底層結(jié)構(gòu),Go?語(yǔ)言的?channel?底層是什么數(shù)據(jù)結(jié)構(gòu)?下面我們就一起來(lái)深入解析一下?channel,需要的朋友可以參考下2022-01-01Golang并發(fā)讀取文件數(shù)據(jù)并寫入數(shù)據(jù)庫(kù)的項(xiàng)目實(shí)踐
本文主要介紹了Golang并發(fā)讀取文件數(shù)據(jù)并寫入數(shù)據(jù)庫(kù)的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06golang使用go test輸出單元測(cè)試覆蓋率的方式
單元測(cè)試覆蓋率是衡量代碼質(zhì)量的一個(gè)重要指標(biāo),重要的代碼文件覆蓋率應(yīng)該至少達(dá)到80%以上,Java 可以通過(guò)JaCoCo 統(tǒng)計(jì)覆蓋率,那么go 項(xiàng)目如何進(jìn)行代碼覆蓋率測(cè)試呢,本文將給大家詳細(xì)的介紹一下golang使用go test輸出單元測(cè)試覆蓋率的方式,需要的朋友可以參考下2024-02-02GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn)
本文主要介紹了GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05利用go-zero在Go中快速實(shí)現(xiàn)JWT認(rèn)證的步驟詳解
這篇文章主要介紹了如何利用go-zero在Go中快速實(shí)現(xiàn)JWT認(rèn)證,本文分步驟通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-10-10Go語(yǔ)言實(shí)現(xiàn)的web爬蟲(chóng)實(shí)例
這篇文章主要介紹了Go語(yǔ)言實(shí)現(xiàn)的web爬蟲(chóng),實(shí)例分析了web爬蟲(chóng)的原理與Go語(yǔ)言的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02