golang 流式读取和发送使用场景示例

 更新时间:2023年12月18日 08:48:05   作者:丿幻灬影丨  
这篇文章主要为大家介绍了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流式读取和发送的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言如何高效的进行字符串拼接(6种方式对比分析)

    Go语言如何高效的进行字符串拼接(6种方式对比分析)

    本文主要介绍了Go语言如何高效的进行字符串拼接(6种方式对比分析),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Go语言tunny的workerWrapper使用教程示例

    Go语言tunny的workerWrapper使用教程示例

    这篇文章主要为大家介绍了Go语言tunny的workerWrapper使用教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • go按行读取文件的三种实现方式汇总

    go按行读取文件的三种实现方式汇总

    最近有遇到需要用go读取文件的情况,下面这篇文章主要给大家介绍了关于go按行读取文件的三种实现方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • Golang中的同步工具sync.Map示例详解

    Golang中的同步工具sync.Map示例详解

    sync.Map是Golang标准库提供的并发安全的Map类型,可以在多个goroutine并发读写Map的场景下不需要加锁,这篇文章主要介绍了Golang中的同步工具sync.Map详解,需要的朋友可以参考下
    2023-05-05
  • Golang: 内建容器的用法

    Golang: 内建容器的用法

    这篇文章主要介绍了Golang: 内建容器的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • golang中time包之时间间隔格式化和秒、毫秒、纳秒等时间戳格式输出的方法实例

    golang中time包之时间间隔格式化和秒、毫秒、纳秒等时间戳格式输出的方法实例

    时间和日期是我们编程中经常会用到的,下面这篇文章主要给大家介绍了关于golang中time包之时间间隔格式化和秒、毫秒、纳秒等时间戳格式输出的方法实例,需要的朋友可以参考下
    2022-08-08
  • Go 基本数据类型与字符串相互转换方法小结

    Go 基本数据类型与字符串相互转换方法小结

    这篇文章主要介绍了Go基本数据类型与字符串相互转换,将string类型转换成基本类型时,必须确保string类型是有效的,文中补充介绍了Go基本数据类型和其字符串表示之间转换,结合实例代码给大家讲解的非常详细,需要的朋友可以参考下
    2024-01-01
  • golang小游戏开发实战之飞翔的小鸟

    golang小游戏开发实战之飞翔的小鸟

    这篇文章主要给大家介绍了关于golang小游戏开发实战之飞翔的小鸟的相关资料,,本文可以带你你从零开始,一步一步的开发出这款小游戏,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-03-03
  • Go语言中多字节字符的处理方法详解

    Go语言中多字节字符的处理方法详解

    这篇文章主要给大家介绍了关于Go语言中多字节字符的处理方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-10-10
  • Go gin框架处理panic的方法详解

    Go gin框架处理panic的方法详解

    本文我们介绍下recover在gin框架中的应用, 首先,在golang中,如果在子协程中遇到了panic,那么主协程也会被终止,文中通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-09-09

最新评论