EventSource JS 开源库 —— Fetch Event Source

该软件包提供了一个更好的 API,用于发出事件源请求(也称为服务器发送的事件),并具备 Fetch API 中的所有功能。默认的浏览器 EventSource API 对允许您发出的请求类型施加了一些限制:您唯一允许传递的参数是 url 和 withCredentials。

该软件包提供了一个更好的 API,用于发出事件源请求(也称为服务器发送的事件),并具备 Fetch API 中的所有功能。

默认的浏览器 EventSource API 对允许您发出的请求类型施加了一些限制:您唯一允许传递的参数是 url 和 withCredentials,因此:

(1) 不能传递请求正文:必须在 URL 中编码执行请求所需的所有信息,而大多数浏览器的 URL 都限制在 2000 个字符以内。

(2)不能输入自定义请求头

(3)只能发出 GET 请求,无法指定其他方法。

(4)如果连接中断,您无法控制重试策略:浏览器会默默地为您重试几次,然后停止。

该库基于 Fetch API,为消费服务器发送的事件提供了另一种接口。它与事件流格式完全兼容,因此如果您已经有一个服务器在发送这些事件,您就可以像以前一样使用它。不过,您现在可以更好地控制请求和响应:

(1)你可以使用任何请求方法/标头/主体,以及 fetch() 提供的所有其他功能。如果浏览器默认的 fetch() 实现不适合您,您甚至可以提供另一种 fetch() 实现。

(2)如果您想在解析事件源之前进行一些自定义验证/处理,您可以访问响应对象。这在应用服务器前有 API 网关(如 nginx)的情况下非常有用:如果网关返回错误,您可能需要正确处理。

(3)如果连接被切断或发生错误,您可以完全控制重试策略。

此外,该库还插入了浏览器的页面可见性 API,因此如果文档被隐藏(如用户最小化窗口),连接就会关闭,并在文档再次可见时自动使用最后一个事件 ID 重试。这样就不会不必要地打开连接,从而减轻了服务器的负担(但如果需要,您也可以选择不使用此行为)。

安装

npm install @microsoft/fetch-event-source

用法

// BEFORE:
const sse = new EventSource('/api/sse');
sse.onmessage = (ev) => {
  console.log(ev.data);
};

// AFTER:
import { fetchEventSource } from '@microsoft/fetch-event-source';

await fetchEventSource('/api/sse', {
  onmessage(ev) {
    console.log(ev.data);
  }
});

您可以传入默认fetch API公开的所有其他参数,例如:

const ctrl = new AbortController();
fetchEventSource('/api/sse', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        foo: 'bar'
    }),
    signal: ctrl.signal,
});

您可以添加更好的错误处理,例如:

class RetriableError extends Error { }
class FatalError extends Error { }

fetchEventSource('/api/sse', {
    async onopen(response) {
        if (response.ok && response.headers.get('content-type') === EventStreamContentType) {
            return; // 一切都很好
        } else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
            // 客户端错误通常是不可重复的
            throw new FatalError();
        } else {
            throw new RetriableError();
        }
    },
    onmessage(msg) {
        // 如果服务器发出一个错误消息,抛出一个异常
        // 这样它就可以通过下面的 onerror 回调来处理:
        if (msg.event === 'FatalError') {
            throw new FatalError(msg.data);
        }
    },
    onclose() {
        // 如果服务器意外关闭连接,请重试:
        throw new RetriableError();
    },
    onerror(err) {
        if (err instanceof FatalError) {
            throw err; // 重新抛出以停止操作
        } else {
            // 不做任何事情自动重试。您还可以在这里返回一个特定的重试间隔。
        }
    }
});

兼容性

不过,您可能需要为旧版 Edge(版本 < 79)多填充 TextDecoder:

require('fast-text-encoding');

贡献

本项目欢迎贡献和建议。大多数贡献要求您同意《贡献者许可协议》(CLA),声明您有权并确实授予我们使用您的贡献的权利。有关详细信息,请访问 https://cla.opensource.microsoft.com

当您提交拉取请求时,CLA 机器人会自动判断您是否需要提供 CLA,并对 PR 进行适当的装饰(如状态检查、评论)。只需按照机器人提供的说明进行操作即可。在使用我们的 CLA 的所有版本库中,您只需这样做一次。

本项目采用了《微软开源行为准则》。如需了解更多信息,请参阅行为准则常见问题解答,或联系 opencode@microsoft.com 以了解更多问题或意见。

项目地址:https://github.com/Azure/fetch-event-source?tab=readme-ov-file

学习,学习,再学习!学,然后知不足。 —— 列宁
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号