2 回答

TA贡献1757条经验 获得超7个赞
您的代码“按预期”运行,并且您在 Go 中编写的内容并不等同于 Node.js 中显示的代码。继续执行代码块,ioutil.ReadAll(resp.Body)因为连接由 CouchDB 服务器保持打开状态。一旦服务器关闭连接,您的客户端代码将打印出来result,ioutil.ReadAll()以便能够将所有数据读取到 EOF。
从CouchDB 文档中关于连续馈送:
连续提要保持打开并连接到数据库,直到明确关闭,并且在发生更改时将其发送给客户端,即近乎实时的。与 longpoll 提要类型一样,您可以设置超时和心跳间隔,以确保连接保持打开状态以进行新的更改和更新。
您可以尝试实验并添加&timeout=1到 URL,这将强制 CouchDB 在 1 秒后关闭连接。然后你的 Go 代码应该打印整个响应。
Node.js 代码的工作方式不同,data每次服务器发送一些数据时都会调用事件处理程序。如果您想实现相同并处理部分更新(在连接关闭之前),则不能使用ioutil.ReadAll()因为它等待 EOF(因此在您的情况下会阻塞),但类似于resp.Body.Read()处理部分缓冲区。这是一个非常简化的代码片段,它演示了这一点,应该给你基本的想法:
package main
import (
"fmt"
"net/http"
"net/url"
"strings"
)
func main() {
client := &http.Client{}
data := url.Values{}
req, err := http.NewRequest("GET", "http://localhost:3030/downloads/_changes?feed=continuous&include_docs=true", strings.NewReader(data.Encode()))
req.Header.Set("Connection", "keep-alive")
resp, err := client.Do(req)
defer resp.Body.Close()
fmt.Println(resp.Status)
if err != nil {
fmt.Println(err)
}
buf := make([]byte, 1024)
for {
l, err := resp.Body.Read(buf)
if l == 0 && err != nil {
break // this is super simplified
}
// here you can send off data to e.g. channel or start
// handler goroutine...
fmt.Printf("%s", buf[:l])
}
fmt.Println()
}
在现实世界的应用程序中,您可能希望确保您buf持有看起来像有效消息的内容,然后将其传递给通道或处理程序 goroutine 以进行进一步处理。

TA贡献1876条经验 获得超5个赞
最后,我能够解决这个问题。该问题与DisableCompression
标志有关。https://github.com/golang/go/issues/16488这个问题给了我一些提示。
通过设置DisableCompression: true
解决了这个问题。client := &http.Client{Transport: &http.Transport{
DisableCompression: true,
}}
我假设默认client := &http.Client{}
发送DisableCompression : false
并且 pouchdb 服务器正在发送压缩的 json,因此接收到的数据被压缩并且 resp.Body.Read 无法读取。
- 2 回答
- 0 关注
- 112 浏览
添加回答
举报