Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 保持活动状态请求更改连续馈送_Http_Go_Couchdb_Keep Alive - Fatal编程技术网

Http 保持活动状态请求更改连续馈送

Http 保持活动状态请求更改连续馈送,http,go,couchdb,keep-alive,Http,Go,Couchdb,Keep Alive,我正在尝试将下面的nodejs代码转换为Go。我必须建立keep-alive http请求来保存数据库服务器的_changes?feed=continuous。然而,我无法在围棋中实现它 var http = require('http') var agent = new http.Agent({ keepAlive: true }); var options = { host: 'localhost', port: '3030', method: 'GET',

我正在尝试将下面的nodejs代码转换为Go。我必须建立keep-alive http请求来保存数据库服务器的_changes?feed=continuous。然而,我无法在围棋中实现它

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();
下面是Go代码

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 Ok,但是没有数据被打印出来,它被卡住了。另一方面,如果我使用longpoll选项ie,那么我正在接收数据。

您的代码“按预期”工作,并且您在Go中编写的代码与Node.js中显示的代码不等效。转到
ioutil.ReadAll(resp.Body)
上的代码块,因为CouchDB服务器保持连接打开。一旦服务器关闭连接,您的客户端代码将打印出
result
作为
ioutil.ReadAll()
将能够读取到EOF的所有数据

关于连续进纸:

连续提要保持打开并连接到数据库,直到显式关闭,并在发生更改时(即近实时)将更改发送到客户端。与longpoll提要类型一样,您可以设置超时和心跳间隔,以确保连接保持打开状态,以便进行新的更改和更新

您可以尝试在URL中添加
&timeout=1
,这将强制CouchDB在1s后关闭连接。然后,您的Go代码应该打印整个响应

Node.js代码的工作方式不同,每次服务器发送数据时都会调用事件
数据
处理程序。如果您希望实现相同的更新并处理部分更新(在连接关闭之前),则不能使用as等待EOF(因此在您的情况下会阻塞),而是使用类似
resp.Body.Read()
的方法来处理部分缓冲区。下面是一段非常简单的代码片段,它演示了这一点,并应为您提供基本的想法:

主程序包
进口(
“fmt”
“net/http”
“网络/网址”
“字符串”
)
func main(){
客户端:=&http.client{}
数据:=url.Values{}
req,err:=http.NewRequest(“GET”http://localhost:3030/downloads/_changes?feed=continuous&include_docs=true,strings.NewReader(data.Encode()))
请求标题集(“连接”,“保持活动”)
resp,err:=client.Do(请求)
延迟响应主体关闭()
fmt打印LN(各自状态)
如果错误!=零{
fmt.Println(错误)
}
buf:=make([]字节,1024)
为了{
l、 错误:=分别读取正文(buf)
如果l==0&&err!=nil{
中断//这是超级简化
}
//在这里,您可以将数据发送到例如channel或start
//处理程序goroutine。。。
fmt.Printf(“%s”,buf[:l])
}
fmt.Println()
}

在现实世界的应用程序中,您可能希望确保您的
buf
包含看起来像有效消息的内容,然后将其传递给通道或处理程序goroutine进行进一步处理。

最后,我能够解决此问题。该问题与
DisableCompression
标志有关。这个问题给了我一些提示

通过设置
DisableCompression:true
修复了该问题。
client:=&http.client{Transport:&http.Transport{
DisableCompression:对,
}}


我假设默认情况下,
client:=&http.client{}
发送
DisableCompression:false
,PockDB服务器发送压缩的json,因此接收到的数据被压缩,resp.Body.Read无法读取。

嗨,我以前尝试过resp.Body.Read,但没有成功。不过,我还是按照你的建议再试了一次,但没有成功。另一方面,nodejs代码可以完美地工作fine@Pram“不工作”是指它仍然无限期地阻塞吗?@Pram只是澄清一下,使用我的代码片段,它没有打印任何数据和阻塞,或者你看到数据通过它然后阻塞了吗?我没有看到任何由fmt.Printf(“%s”,buf[:l])打印的数据在allI编辑了我的答案,并发布了最小的完整文件可执行示例以进行分类。我刚刚在Docker中对本地运行的CouchDB进行了测试,它的行为与Node.js代码相同(应该打印出一些数据,然后阻塞)。如果这个在你的Env中工作得很好,那么你的代码中还有其他的问题。你应该考虑使用一个库来为你做这项工作。在那里,@Flimzy我曾使用过Kivik,但我面临着类似的问题。因此决定直接与couchdb沟通。谢谢你的链接。这个问题看起来和你在这里描述的完全不同。无论如何,我用一些建议回答了你的Kivik问题。非常抱歉,我使用的是PockDB,我认为API是类似的。因此提到couchDb.API是相似的,但它们的底层功能完全不同。PockDB完全在浏览器中运行,CouchDB在服务器上运行。