golang 流式读取和发送使用场景示例
作者:丿幻灬影丨
这篇文章主要为大家介绍了golang 流式读取和发送使用场景示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
场景
- 部分大模型(如gpt)的流式读取,可以增加用户体验。
- gin框架的流式问答,与前端交互。
使用方法
- 我在使用框架req 的时候,发现无法从resp.Body流式读取数据,只能完整读出来
原因是框架自动帮我们读取了resp,导致我们无法读取流式的消息。
正常我们获取返回值应该是这样的:
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) } }
- 现在我们知道了如何从外部读取流式数据,那么我们如何利用web框架发送流式数据呢?
以gin框架为例
可以使用func (c *Context) Stream(step func(w io.Writer) bool) bool
函数
==具体使用方法如下==(这里我用了自己的代码做了演示):
如果前端有需求,需要加上Header
c.Header("Content-Type", "application/octet-stream")
用bufio缓冲区向前端写数据
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吧,按官方文档来说,是为了将写好的数据发送给客户端。
// 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流式读取和发送的详细内容,更多关于golang流式读取和发送的资料请关注脚本之家其它相关文章!