在调用 res.end() 之前,SSE 事件不会到达客户端

Sri*_*ddy 7 gzip node.js server-sent-events eventsource

相同的代码以前可以工作,但我不知道为什么现在不起作用。请帮忙。

我的问题是,当我使用 SSE 进行实时数据共享时。应该在 res.write( data:${JSON.stringify(dataObject)}\n\n) 上发送的数据对象在调用 res.end() 之前不会发送,并且所有数据都是事件流立即发送。

response.writeHead(200, {
    Connection: "keep-alive",
    "Content-Type": "text/event-stream",
    "Cache-Control": "no-cache",
    "Access-Control-Allow-Origin": '*',
    'Content-Encoding':'identity' // this with and without this
});

let syncher= setInterval(() => { 
    if(response.finished){ // If response ended the  interval is cleared
        clearInterval(syncher);
        return;
    }else{
        let dataToSend = getEventData(user,event);
        if(! dataToSend ){
            response.write('data:{close:true}');
            clearInterval(syncher);
            return;
        }
        response.write(`data:${JSON.stringify(dataToSend)}\n\n`);
        response.flushHeaders(); // Also tried with response.flush()
        if(dataToSend.close){
            delEventData(user,event);
            response.end();
        }
    }
}, 500);
Run Code Online (Sandbox Code Playgroud)

上面的代码位于服务器端,这也有关闭侦听器来关闭连接

const ev = new EventSource(conf.apiUrl+'/getStatus/'+ (userData.id || '') );
  let data = '';
  ev.onmessage = eventData=>{
    data = JSON.parse(eventData.data);
    if(!data){
      setState('progress '+data.completedSoFar)
      return;
    }
    if(!data.close){

    }else{
      if(data.success){
        console.log('Done Successfully')
      ev.close();
    }
  }
Run Code Online (Sandbox Code Playgroud)

这是我的客户端代码

我不知道为什么事件监听器没有获取数据流,当我在互联网上搜索此问题时,我只发现使用压缩中间件时会出现此问题。我在我的应用程序中没有使用任何压缩中间件。我使用的是nodejs v11.4.0。我猜测当我发出 eventsource 请求时,chrome 默认添加 gzip 编码,并且节点使用它来将响应编码标头设置为 gzip 我尝试删除并替换它,但没有成功,这导致了此问题?

这是我的 eventSource 请求的请求和响应标头

如果我犯了任何错误,请原谅我的语法。

感谢帮助。干杯!

小智 5

Nextjs 基本上是压缩您的数据以使其传输速度更快。不幸的是,这使得我们在刷新缓存之前无法看到数据(我的猜测是渲染行为已经改变,因为压缩改变了内容)。您可以通过将其包含compress: false在 next.config 中来完全禁用压缩。

在这里发现,包含以下标头可以避免特定端点的压缩: res.setHeader("Cache-Control", "no-cache, no-transform");

注意:这会增加带宽/资源使用!HTTP 压缩可以将数据大小减少70%


Sri*_*ddy 2

经过大量的调试和研究。问题出在 webpack-dev-server 上,它压缩了我的响应。有关更多信息,请参阅https://github.com/facebook/create-react-app/issues/966