@microsoft/fetch-event-source 使用

@microsoft/fetch-event-source 使用文档

简介

@microsoft/fetch-event-source 是一个用于处理服务器发送事件(Server-Sent Events, SSE)的客户端库。它提供了一个可靠的方式来建立与服务器的长连接,接收实时更新,特别适用于流式API响应、实时通知和数据流等场景。

与传统的 EventSource API相比,@microsoft/fetch-event-source 提供了更多的功能和更好的错误处理机制,同时保持了简单易用的特性。

主要特性

  • 基于标准的 fetch API
  • 支持自动重连和退避策略
  • 提供完整的错误处理机制
  • 支持自定义请求头和认证
  • 支持中止连接
  • TypeScript 类型支持

安装

bash 复制代码
# 使用 npm
npm install @microsoft/fetch-event-source

# 使用 yarn
yarn add @microsoft/fetch-event-source

# 使用 pnpm
pnpm add @microsoft/fetch-event-source

基本用法

javascript 复制代码
import { fetchEventSource } from '@microsoft/fetch-event-source';

// 建立连接
fetchEventSource('/api/events', {
  method: 'GET',
  headers: {
    'Accept': 'text/event-stream',
    // 可以添加其他请求头,如认证信息
  },
  onmessage(event) {
    // 处理接收到的消息
    console.log(event.data);
  },
  onopen(response) {
    // 连接打开时的回调
    console.log('Connection opened:', response.status);
  },
  onerror(error) {
    // 错误处理
    console.error('Error:', error);
  },
  onclose() {
    // 连接关闭时的回调
    console.log('Connection closed');
  }
});

API 参考

fetchEventSource(url, options)

建立与服务器的SSE连接。

参数
  • url (string): 服务器端点URL
  • options (object): 配置选项
    • method (string): HTTP请求方法,默认为 'GET'
    • headers (object): 请求头
    • body (string | FormData | URLSearchParams): 请求体
    • credentials (string): 凭证模式,如 'include', 'omit', 'same-origin'
    • signal (AbortSignal): 用于中止请求的信号
    • openWhenHidden (boolean): 当页面不可见时是否保持连接,默认为 true
    • fetch (function): 自定义fetch实现
    • onopen (function): 连接打开时的回调
    • onmessage (function): 接收消息时的回调
    • onclose (function): 连接关闭时的回调
    • onerror (function): 发生错误时的回调
    • retry (object | function): 重试策略配置
重试策略
javascript 复制代码
{
  retry: {
    // 初始重试延迟(毫秒)
    initialRetryDelayMs: 1000,
    
    // 最大重试延迟(毫秒)
    maxRetryDelayMs: 30000,
    
    // 退避因子,每次重试延迟会乘以这个因子
    backoffFactor: 1.5,
    
    // 重试延迟的随机因子
    jitterFactor: 0.1,
    
    // 自定义重试条件
    retryStatusCodes: [500, 502, 503, 504]
  }
}

也可以提供一个函数来自定义重试逻辑:

javascript 复制代码
{
  retry: (retries, error) => {
    if (error.status === 401) return false; // 不重试认证错误
    if (retries > 5) return false; // 最多重试5次
    return true; // 其他情况重试
  }
}

事件格式

服务器发送的事件应该遵循SSE格式规范:

vbnet 复制代码
event: eventName
data: {"key": "value"}

每个事件由一个或多个字段组成,字段之间用换行符分隔,事件之间用两个换行符分隔。

错误处理

库提供了多种错误类型:

  • FatalError: 表示不应该重试的错误
  • RetriableError: 表示可以重试的错误

可以在 onerror 回调中处理这些错误:

javascript 复制代码
onerror(error) {
  if (error instanceof FatalError) {
    console.error('Fatal error, giving up:', error);
  } else {
    console.log('Retriable error, retrying:', error);
  }
}

中止连接

使用 AbortController 来中止连接:

javascript 复制代码
const controller = new AbortController();

fetchEventSource('/api/events', {
  signal: controller.signal,
  // 其他选项...
});

// 在需要时中止连接
controller.abort();

服务器实现示例

服务器端需要实现SSE规范,以下是一个简单的Node.js Express示例:

javascript 复制代码
const express = require('express');
const app = express();

app.get('/api/events', (req, res) => {
  // 设置SSE所需的响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  // 发送事件
  const sendEvent = (data, eventName = 'message') => {
    res.write(`event: ${eventName}\n`);
    res.write(`data: ${JSON.stringify(data)}\n\n`);
  };

  // 发送初始事件
  sendEvent({ message: 'Connected!' }, 'open');

  // 定期发送更新
  const interval = setInterval(() => {
    sendEvent({ time: new Date().toISOString() });
  }, 1000);

  // 清理
  req.on('close', () => {
    clearInterval(interval);
  });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

最佳实践

  1. 始终处理错误 :实现 onerror 回调以处理连接问题
  2. 实现重连逻辑:使用内置的重试机制处理临时网络问题
  3. 在不需要时关闭连接 :使用 AbortController 在组件卸载时中止连接
  4. 考虑后台行为 :根据需要配置 openWhenHidden 选项
  5. 处理认证:在请求头中包含必要的认证信息
相关推荐
求知若渴,虚心若愚。1 分钟前
Error reading config file (/home/ansible.cfg): ‘ACTION_WARNINGS(default) = True
linux·前端·ansible
LinDaiuuj1 小时前
最新的前端技术和趋势(2025)
前端
一只小风华~1 小时前
JavaScript 函数
开发语言·前端·javascript·ecmascript·web
程序猿阿伟2 小时前
《不只是接口:GraphQL与RESTful的本质差异》
前端·restful·graphql
若梦plus3 小时前
Nuxt.js基础与进阶
前端·vue.js
樱花开了几轉4 小时前
React中为甚么强调props的不可变性
前端·javascript·react.js
风清云淡_A4 小时前
【REACT18.x】CRA+TS+ANTD5.X实现useImperativeHandle让父组件修改子组件的数据
前端·react.js
小飞大王6664 小时前
React与Rudex的合奏
前端·react.js·前端框架
若梦plus4 小时前
React之react-dom中的dom-server与dom-client
前端·react.js
若梦plus4 小时前
react-router-dom中的几种路由详解
前端·react.js