为了账号安全,请及时绑定邮箱和手机立即绑定

从 API 流式传输数据

从 API 流式传输数据

Go
MMMHUHU 2023-01-03 10:09:12
我正在尝试从电子邮件测试工具 mailhog 中提取有关进入 API 的邮件数据。如果我使用调用来获取电子邮件列表,例如 GET /api/v1/messages,我可以毫无问题地将这些数据加载到一个结构中,并打印出我需要的值。但是,如果我使用一个不同的端点,它本质上是一个新的电子邮件流,我会有不同的行为。当我运行我的 go 应用程序时,我没有得到任何输出。我是否需要像 while 循环一样不断地监听端点以获取输出?我的最终目标是在电子邮件进入时从中提取一些信息,然后将它们传递给不同的功能。这是我尝试访问流式传输端点 https://github.com/mailhog/MailHog/blob/master/docs/APIv1.mdres, err := http.Get("http://localhost:8084/api/v1/events")if err != nil {    panic(err.Error())}body, err := ioutil.ReadAll(res.Body)if err != nil {    panic(err.Error())}var data Emailjson.Unmarshal(body, &data)fmt.Printf("Email: %v\n", data)如果我在具有相同端点的 mailhog 服务上执行 curl 请求,我会在收到邮件时得到输出。但是我似乎无法弄清楚为什么我的 go 应用程序没有得到任何输出。该应用程序确实保持运行,只是我没有得到任何输出。如果这是一个非常简单的问题,我是 Go 的新手,所以很抱歉
查看完整描述

1 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

ioutil.ReadAll文档:

ReadAll 从 r 读取直到出现错误或 EOF 并返回它读取的数据。

当您用来读取常规端点的正文时,它会起作用,因为有效负载有一个EOF:服务器使用标头来Content-Length告诉正文响应有多少字节,一旦客户端读取了那么多字节,它就会明白它已经读取了全身上下都可以停下来。

但是,您的“流”端点没有使用,因为正文的大小未知,它应该在事件到来时写入事件,因此在这种情况下Content-Length您不能使用。ReadAll通常,在这种情况下,您应该逐行阅读,其中每行代表一个事件。bufio.Scanner正是这样做的:

res, err := http.Get("http://localhost:8084/api/v1/events")

if err != nil {

    panic(err.Error())

}

scanner := bufio.NewScanner(res.Body)

for e.scanner.Scan() {

    if err := e.scanner.Err(); err != nil {

        panic(err.Error())

    }

    event := e.scanner.Bytes()

    var data Email

    json.Unmarshal(event, &data)

    fmt.Printf("Email: %v\n", data)

}

curl可以按预期处理响应,因为它会检查端点是否会流式传输数据,因此它会相应地做出反应。添加对问题的响应可能会有所帮助curl。


查看完整回答
反对 回复 2023-01-03
  • 1 回答
  • 0 关注
  • 77 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信