处理流式 HTTP 响应

问题描述 投票:0回答:1

我有以下示例,它连接到 HTTP 服务,该服务将响应以块流的形式传回以创建 JSON 结构。对于每个块,我的代码都会附加一个带有各个行的字节

rb
数组。然而,我的问题是试图解决
rb
何时完成,以便我可以对其进行解码。

我在这里遗漏了一些明显的东西吗?

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "io"
    "net/http"
)

func main() {

    body := []byte("test")

    resp, err := http.Post("http://localhost:8281/tap", "application/json", bytes.NewReader(body))
    if err != nil {
        fmt.Printf("%v\n", err)
        return
    }
    defer resp.Body.Close()
    fmt.Printf("Status: [%s]\n", resp.Status)
    fmt.Println()
    //var rb []byte
    reader := bufio.NewReader(resp.Body)
    var rb []byte

    for {

        line, err := reader.ReadBytes('\n')
        if err != nil {
            if err == io.EOF {
                break
            }
            fmt.Printf("Error reading streamed bytes %v", err)
        }
        rb = append(rb, line...)

        fmt.Println(rb)

    }
}

go http stream
1个回答
0
投票

忽略程序中的错误,

rb
当循环中断时就完成了。

该程序确实有错误:

  • 程序仅在 EOF 时跳出循环。如果出现任何其他类型的错误,程序将永远旋转。
  • 程序不处理ReadBytes返回数据和错误的情况。发生这种情况的一个简单示例是当响应不以分隔符结尾时。

看起来您的目标是吃掉对

rb
的全部回复。使用 io.ReadAll 这样做:

rb, err := io.ReadAll(resp.Body)
if err != nil {
    // handle error
}

如果你想将响应体解码为 JSON,那么更好的方法是让 JSON decoder 读取响应体:

var data SomeType
err := json.NewDecoder(resp.Body).Decode(&data)
© www.soinside.com 2019 - 2024. All rights reserved.