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 關注
- 148 瀏覽
添加回答
舉報