使用Koa进行服务器发送的事件

时间:2018-11-13 21:04:40

标签: server-sent-events koa koa-router

在Express中实现了SSE后,我想对Koa这样做,就像这样:

const Koa = require('koa');
const Router = require('koa-router');

const app = new Koa();
const router = new Router();

router.get('/stream', (ctx, next) => {
  ctx.set({
    'Access-Control-Allow-Origin': '*',
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    Connection: 'Keep-Alive',
  });

  const id = new Date().toLocaleTimeString();
  ctx.res.write(`id: ${id}'\n`);
  ctx.res.write(`data: CONNECTION ESTABLISHED)}\n\n`);
  next();
});

app.use(router.routes());

app.listen(8080, () => {
  console.log('Listening on port 8080');
});

对于我的客户,在React组件的构造函数中:

constructor(props) {
    super(props);

    this.state = {
      source: new EventSource("http://localhost:8080/stream"),
    };
}

但是由于某些原因,我在客户端收到了以下错误消息:

  

Firefox无法在http://localhost:8080/stream与服务器建立连接。

即使我的客户对/stream的请求确实通过了(但未发回任何答复)。

是什么原因导致SSE连接出现此问题?

我有一台Koa服务器在给定的端口上侦听,这是一种使用正确的标头数据捕获初始GET请求的路由,但是它失败了。

1 个答案:

答案 0 :(得分:0)

这里的主要问题是,一旦所有中间件运行完毕,Koa就会“结束” HTTP响应。

这在函数结束后立即发生,例如当函数已解决承诺时函数是否返回了promise。要保持连接开放并规避Koa的响应处理,您需要确保该功能“永不结束”,而实现此目的的最佳方法是简单地返回一个无法解决的承诺。

您正在有效地接管响应处理并阻止Koa这样做。此时,您就可以开始使用套接字了。

我不确定在Koa中是否存在更合适的方法来解决此问题,但这就是我过去解决此问题的方式。