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语言用map实现堆栈功能的方法

    Go语言用map实现堆栈功能的方法

    这篇文章主要介绍了Go语言用map实现堆栈功能的方法,实例分析了Go语言使用map操作堆栈的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go语言清除文件中空行的方法

    Go语言清除文件中空行的方法

    这篇文章主要介绍了Go语言清除文件中空行的方法,实例分析了Go语言针对文件的操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Golang中指针的使用详解

    Golang中指针的使用详解

    Golang是一门支持指针的编程语言,指针是一种特殊的变量,存储了其他变量的地址。通过指针,可以在程序中直接访问和修改变量的值,避免了不必要的内存拷贝和传递。Golang中的指针具有高效、安全的特点,在并发编程和底层系统开发中得到广泛应用
    2023-04-04
  • 使用Go语言实现简单聊天系统

    使用Go语言实现简单聊天系统

    本文介绍了如何使用Go语言和WebSocket技术构建一个简单的多人聊天室系统,包括客户端连接管理、消息广播和并发处理,最后,通过编写main.go、hub.go和client.go等核心代码模块,具有一定的参考价值,感兴趣的可以了解一下
    2024-10-10
  • go语言字符串的拼接和切片方法总结

    go语言字符串的拼接和切片方法总结

    在go语言中,因为字符串只能被访问,不能被修改,所以进行字符串拼接的时候,golang都需要进行内存拷贝,造成一定的性能消耗,这篇文章主要给大家介绍了关于go语言字符串的拼接和切片的相关资料,需要的朋友可以参考下
    2022-11-11
  • Go并发编程之死锁与活锁的案例分析

    Go并发编程之死锁与活锁的案例分析

    死锁就是在并发程序中,两个或多个线程彼此等待对方完成操作,从而导致它们都被阻塞,并无限期地等待对方完成;活锁就是程序一直在运行,但是无法取得进展。本文将从一些案例出发,分析一下它们,希望对大家有所帮助
    2023-04-04
  • 基于golang如何实现error工具包详解

    基于golang如何实现error工具包详解

    Go 语言使用 error 类型来返回函数执行过程中遇到的错误,下面这篇文章主要给大家介绍了关于如何基于golang实现error工具包的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-09-09
  • golang int64转int的方法

    golang int64转int的方法

    这篇文章主要介绍了golang int64转int,本文给大家提供两种方法 ,将 golang int64 转换为golang int,结合实例代码给大家分享转换方法,需要的朋友可以参考下
    2023-01-01
  • Go语言实现socket实例

    Go语言实现socket实例

    这篇文章主要介绍了Go语言实现socket的方法,实例分析了socket客户端与服务器端的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • 详解Golang中的交叉编译

    详解Golang中的交叉编译

    在 Golang 中,交叉编译指的是在同一台机器上生成针对不同操作系统或硬件架构的二进制文件,这在开发跨平台应用或构建特定平台的发布版本时非常有用,本文就详细的给大家介绍一下Golang中的交叉编译,需要的朋友可以参考下
    2023-08-08

最新评论