【问题标题】:Server Side Events (SSE) not reaching client side服务器端事件 (SSE) 未到达客户端
【发布时间】:2016-10-28 12:19:49
【问题描述】:

我正在使用 MEAN,并且正在尝试从服务器端接收事件。为此,我使用 EventSource 但它不起作用。

我看到连接是如何打开的,但我没有从服务器收到任何消息。我可以在节点控制台中看到消息是如何发送的,但在客户端什么都没有(浏览器控制台)。

我在学习我找到的所有教程时有点迷茫,但使用完全相同的代码却无法正常工作。

在客户端,这是我的 AngularJS 代码:

  var source = new EventSource('/api/payments/listen');

  source.addEventListener('open', function(e) {
    console.log('CONNECTION ESTABLISHED');
  }, false);

  source.addEventListener('message', function (e) {

    $scope.$apply(function () {
      console.log('NOTIFICATION');
      console.log(e.data);
    });

  }, false);

  source.onmessage = function (e) {
    console.log('NOTIFICATION!');
    console.log(e);
  };

  source.addEventListener('error', function(e) {
    if (e.readyState === EventSource.CLOSED) {
      console.log('CONNECTION CLOSED');
    }
  }, false);

服务器端代码:

exports.listen = function (req, res) {

  if (req.headers.accept && req.headers.accept === 'text/event-stream') {

    if ( req.url === '/api/payments/listen' ) {
      sendSSE(req, res);
    }
    else {
     res.writeHead(404);
     res.end();
    }

  }
  else
    res.end();

};

function sendSSE(req, res) {

  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  var id = (new Date()).toLocaleTimeString();

  // Sends a SSE every 5 seconds on a single connection.
  setInterval(function() {
    constructSSE(res, id, data);
  }, 5000);

  constructSSE(res, id, data);
}

function constructSSE(res, id, data) {

  res.write('id: ' + id + '\n');
  res.write('data: ' + JSON.stringify(data) + '\n\n');

}

有什么建议吗?有什么建议吗?

编辑

我不知道是什么导致了这个问题,但我已经使用 Simple-SSE 让它工作了,这是一个用于服务器端事件的有用且小的库。

现在,它正在按预期工作。

这里是给想要尝试的人的链接: https://github.com/Lesterpig/simple-sse

谢谢 =)

【问题讨论】:

  • 在 PHP 中,您将使用带有 sleep 的无限 while 循环,否则线程将关闭。也许是一样的?
  • 你在哪里发送服务器端事件?我没有看到事件被调用,我看到很多客户端侦听器,没有从服务器发出。
  • @EmilS.Jørgensen 我会检查一下,但我发现没有一个实现示例使用类似的东西。此外,在与服务器建立连接后,我在客户端看不到任何“CONNECTION CLOSED”。谢谢!
  • @magreenberg 它应该是一个流,所以你在管道中写一些东西,内容直接进入客户端。在这种情况下,这是通过“res.write”完成的。不管怎样,我也去看看。
  • 试过用 curl 调用 /api/payments/listen 吗?它的行为是否符合您的预期?

标签: javascript angularjs node.js express server-sent-events


【解决方案1】:

希望这对遇到与我相同的问题的人有所帮助。在无法从服务器接收消息之后,我来到了这个问题,尽管我的代码中的所有内容似乎都是它应该的样子。在看到这个库帮助我挖掘了源代码并找到了答案之后。如果您正在使用任何压缩库,例如我在我的 express 应用程序中,您需要在写入后刷新响应。否则,压缩不会像协议预期的那样发送消息。例如 res.write("数据:hi\n\n") res.flush()

【讨论】:

  • 工作就像一个魅力。感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 2017-09-24
  • 1970-01-01
  • 2020-07-16
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多