亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

保持活動請求 _change 連續供稿

保持活動請求 _change 連續供稿

Go
慕絲7291255 2022-06-01 11:42:02
我正在嘗試將以下 nodejs 代碼轉換為 Go。我必須向 PouchDB 服務器的 _changes?feed=continuous 建立保持活動 http 請求。但是,我無法在 Go 中實現它。var http = require('http')var agent = new http.Agent({    keepAlive: true});var options = {   host: 'localhost',   port: '3030',   method: 'GET',   path: '/downloads/_changes?feed=continuous&include_docs=true',   agent };var req = http.request(options, function(response) {    response.on('data', function(data) {        let val = data.toString()        if(val == '\n')            console.log('newline')        else {            console.log(JSON.parse(val))            //to close the connection            //agent.destroy()        }    });    response.on('end', function() {        // Data received completely.        console.log('end');    });    response.on('error', function(err) {        console.log(err)    })});req.end();下面是圍棋代碼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)fmt.Println(resp.Status)if err != nil {    fmt.Println(err)}defer resp.Body.Close()result, err := ioutil.ReadAll(resp.Body)if err != nil {    fmt.Println(err)}fmt.Println(result)我得到狀態 200 好的,但沒有打印數據,它卡住了。另一方面,如果我使用 longpoll 選項,即。http://localhost:3030/downloads/_changes?feed=longpoll然后我正在接收數據。
查看完整描述

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 以進行進一步處理。



查看完整回答
反對 回復 2022-06-01
?
慕運維8079593

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 無法讀取。


查看完整回答
反對 回復 2022-06-01
  • 2 回答
  • 0 關注
  • 148 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號