首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >express.js not streaming chunked 'text/event-stream‘响应

express.js not streaming chunked 'text/event-stream‘响应
EN

Stack Overflow用户
提问于 2015-04-23 04:11:30
回答 2查看 2.4K关注 0票数 1

我正在尝试从express.js端点发送SSE text/event-stream响应。我的路由处理程序如下所示:

代码语言:javascript
复制
function openSSE(req, res) {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream; charset=UTF-8',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive',
    'Transfer-Encoding': 'chunked'
  });

  // support the polyfill
  if (req.headers['x-requested-with'] == 'XMLHttpRequest') {
    res.xhr = null;
  }

  res.write(':' + Array(2049).join('\t') + '\n'); //2kb padding for IE
  res.write('id: '+ lastID +'\n');
  res.write('retry: 2000\n');
  res.write('data: cool connection\n\n');

  console.log("connection added");
  connections.push(res);
}

稍后,我会调用:

代码语言:javascript
复制
function sendSSE(res, message){
    res.write(message);
    if (res.hasOwnProperty('xhr')) {
        clearTimeout(res.xhr);
        res.xhr = setTimeout(function () {
          res.end();
          removeConnection(res);
        }, 250);
    }
}

我的浏览器发出并保存请求:

任何响应都不会被推送到浏览器。我的事件都不会被触发。如果我杀了express.js服务器。响应会突然耗尽,并且每个事件都会立即命中浏览器。

如果我更新我的代码,在res.write(message)行后面添加res.end(),它会正确地刷新流,但是它会回退到事件轮询,并且不会流式处理响应。

我试着在响应的头部添加填充,就像我在其他SO post中看到的res.write(':' + Array(2049).join('\t') + '\n');一样,它可以触发浏览器耗尽响应。

我怀疑这是express.js的问题,因为我之前在nodes原生http服务器上使用过这段代码,它工作正常。所以我想知道是否有什么方法可以绕过express对响应对象的包装。

EN

回答 2

Stack Overflow用户

发布于 2015-04-23 06:14:26

这是我在我的项目中工作的代码。

服务器端:

代码语言:javascript
复制
router.get('/listen', function (req, res) {
    res.header('transfer-encoding', 'chunked');
    res.set('Content-Type', 'text/json');

    var callback = function (data) {
        console.log('data');
        res.write(JSON.stringify(data));
    };

    //Event listener which calls calback.
    dbdriver.listener.on(name, callback);

    res.socket.on('end', function () {
        //Removes the listener on socket end
        dbdriver.listener.removeListener(name, callback);
    });
});

客户端:

代码语言:javascript
复制
xhr = new XMLHttpRequest();
xhr.open("GET", '/listen', true);
xhr.onprogress = function () {
    //responseText contains ALL the data received
    console.log("PROGRESS:", xhr.responseText)
};
xhr.send();
票数 2
EN

Stack Overflow用户

发布于 2019-10-31 05:37:00

我也在努力解决这个问题,所以在浏览和阅读之后,我通过为response对象设置一个额外的头来解决了这个问题:

代码语言:javascript
复制
res.writeHead(200, {
  "Content-Type": "text/event-stream",
  "Cache-Control": "no-cache",
  "Content-Encoding": "none"
});

长话短说,当EventSource与服务器协商时,它正在发送一个Accept-Encoding: gzip, deflate, br报头,该报头使express使用Content-Encoding: gzip报头进行响应。因此对于这个问题有两种解决方案,第一种是向响应中添加一个Content-Encoding: none头,第二种是(gzip)压缩响应。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29807834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档