首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Koa SSE连接重新连接

Koa SSE连接重新连接
EN

Stack Overflow用户
提问于 2018-11-14 08:21:28
回答 2查看 887关注 0票数 2

我已经使用Koa建立了一个SSE连接,如下所示:

代码语言:javascript
复制
const Koa = require('koa');
const Router = require('koa-router');

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

// Sets up the HTTP header and sends a message via SSE
function writeSSE(ctx, message) {
  ctx.res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    Connection: 'keep-alive',
    'Access-Control-Allow-Origin': '*',
  });

  ctx.res.write(`id: 01\n`);
  ctx.res.write(`data: ${message}\n\n`);
}

// Router Middleware
router.get('/stream', (ctx, next) => {
  writeSSE(ctx, 'Stream reached.');
});

app.use(router.routes()).use(router.allowedMethods());

app.listen(8080);

当我的React组件开始连接时,如下所示:

代码语言:javascript
复制
new EventSource("http://localhost:8080/stream")

然后,组件在后端接收由writeSSE方法发送的答案。

但出于某种原因,每隔3秒左右就会到达/stream 端点,就好像连接正在重新建立一样。

而前端的错误侦听器每次都捕获一个连接事件。

代码语言:javascript
复制
this.state.source.onerror = (e) => {         
   if (e.target.readyState == EventSource.CONNECTING) {
     console.log("Connecting...");
   }
};

在后端,ctx.response等于{ status: 404, message: 'Not Found', header: {} }

有谁知道这个问题的原因吗?这和我使用Koa的方式有关吗?

EN

回答 2

Stack Overflow用户

发布于 2019-03-20 15:26:40

这有点太晚了,但我将编写使用Koa的sse的经验。

  • 首先,直接使用ctx.res并不太受Koa的欢迎,如果您还想使用它,请确保将ctx.respond = false用于绕过koa响应机制。
  • 在我的经验中,流是在Koa中使用SSE的最佳方法,您可以这样做:
代码语言:javascript
复制
const stream = require('stream');
const koa = require('koa');


const app = new koa();

app.use(async ctx => {
  ctx.set({
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
    });
  ctx.status = 200;
  const stream = new stream.PassThrough()
  ctx.body = stream; // here koa will pipe the ctx.res to stream and end the ctx.res when ever the stream ends.
  let counter = 5;
  const t = setInterval(() => {
    stream.write(`data: hi from koa sse ${counter}`);
    counter--;
    if (counter === 0) {
        stream.end();
      clearInterval(t);
    }
  }, 1000);
});

希望这对任何人都能在科亚上玩SSE游戏。

PS:如果代码有什么问题,请告诉我,我会改正的。

票数 3
EN

Stack Overflow用户

发布于 2018-12-29 01:40:20

我正在为SSE实现一个基于Koa的服务器。我遇到了同样的问题,下面是我的想法/工作解决方案:

据我所知,onmessage和onerror不断被调用的原因是客户端的EventSource对象正在发出错误事件。这会导致连接断开,从而导致客户端发送另一个请求,以将流初始化到服务器。从这里开始,这个过程将无限期地重复下去。

根据我自己的测试,由于从服务器发送回来的数据,EventSource发出了一个错误。根据文档,除了“文本/事件流”之外,作为内容类型的200个响应将导致失败。

在您的示例中,您已经将响应声明为“text/event-stream”,并将字符串传递到ctx.res.write方法中。虽然这看起来是正确的,而且实际上在使用类似的代码和Express时是有效的,但在Koa中它似乎不起作用。但是,如果您更改要写入流响应的“数据”(如本例这里 ),则会发现连接建立正确。

也许可以尝试以下几点:

代码语言:javascript
复制
//require Passthrough
const PassThrough = require('stream').PassThrough;

//then, in your writeSSE function, try this:
let stream = new PassThrough();
stream.write(`data: ${message}\n\n`);
ctx.res.write(stream);

我不能百分之百确定这一变化的原因。我最好的猜测是,Koa的ctx对象有一些东西可以防止普通字符串或模板文本被视为有效的文本/事件流数据,但这完全是假设(这就引出了为什么它在Express中工作的问题,但希望有一个更有知识的人能够为我们两个人回答这个问题)。从我在网上看到的其他片段来看,流方法是在Koa中采用的方法。

我不知道你的结果会是什么,因为看起来你可能使用了一个不同于我的版本的Koa,但我会尝试一下。我能够正确地建立起我的连接,做出这个小小的改变。

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

https://stackoverflow.com/questions/53295738

复制
相关文章

相似问题

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