【问题标题】:Cloudflare Workers - SSECloudflare Workers - SSE
【发布时间】:2020-12-31 00:33:27
【问题描述】:

有没有办法使用 cloudflare 工作人员进行服务器端事件? 我只找到了一种方法,但它会在返回响应后立即停止。

    const { readable, writable } = new TransformStream();
    const response = {
      headers: new Headers({
        'Content-Type': 'text/event-stream',
        'Cache-Control': 'no-cache',
        'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept',
        Connection: 'keep-alive',
      }),
      status: 101
    };

    setInterval(() => {
      const encoder = new TextEncoder();
      const writer = writable.getWriter();
      writer.write(encoder.encode(`data: hello\n\n`));
    }, 5000);

    return new Response(readable, response);

【问题讨论】:

  • 对不起,我忘了包含间隔,所以我更新了它!

标签: javascript events cloudflare fetch-api cloudflare-workers


【解决方案1】:

您的示例代码有两个问题:

  • 您不应设置状态码 101。状态码 101 表示“交换协议”,即服务器将开始使用 HTTP 以外的内容。例如,这与 WebSockets 一起使用。但是,您的示例代码没有使用不同的协议——它只是带有流式响应主体的常规 HTTP。 Workers 运行时不支持切换协议,除了 WebSocket,因此它会拒绝提供 101 状态代码,而是向客户端提供错误。
  • 您在每个间隔都调用getWriter(),但您只能有一个 Writer,所以在第一个间隔之后,调用失败。您应该在设置间隔之前调用一次getWriter(),然后重用该编写器。

在预览版中运行代码时,这两个问题都会在 JavaScript 控制台中显示为错误(例如,在 cloudflareworkers.com 或 Cloudflare 仪表板中,或使用 wrangler previewwrangler dev)。我建议使用预览来调试您的代码,因为它可以告诉您客户端不可见的错误。

以下代码在预览中适用于我——文本按预期每 5 秒添加到响应中:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const { readable, writable } = new TransformStream();
  const encoder = new TextEncoder();
  const writer = writable.getWriter();
  setInterval(() => {
    writer.write(encoder.encode(`data: hello\n\n`));
  }, 5000);

  return new Response(readable);
}

【讨论】:

  • 它不起作用,因为没有“连接”和其他标题它不起作用,但是使用正确的标题它会起作用,谢谢。
  • 我的例子只是为了展示如何进行流式传输;我不知道您的应用还需要哪些其他标头。但请注意,您不能在 Workers 中设置 Connection 标头。但是,您没有理由需要这样做。 Connection 标头对流式响应主体或 SSE 没有任何影响;它只控制响应正文结束后是否可以在同一连接上发送另一个请求。
  • 一个问题如何检查客户端是否关闭。
  • @Tector 如果客户端关闭连接,则立即取消 Worker,包括取消所有传出的 fetch() 请求。如果您想在客户端断开连接时执行其他操作,则需要使用 waitUntil() 来防止 worker 被取消,并检查 write() 是否抛出异常以检测连接关闭。 (注意 write() 返回一个你必须等待才能捕获异常的承诺。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多