@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. 处理认证:在请求头中包含必要的认证信息
相关推荐
星栈10 小时前
Rust 单二进制部署,真没你想的那么“单”
前端·后端
angerdream10 小时前
Android手把手编写儿童手机远程监控App之webrtc聊天数据通道
前端
浩风祭月10 小时前
受够了每次切分支都要重装依赖:一份 Git 工作流优化指南
前端·ai编程
谭光志10 小时前
如何从零开始实现一个 AI Agent CLI
前端·javascript·ai编程
半个落月10 小时前
彻底搞懂 JavaScript 变量提升(Hoisting)—— 从现象到底层原理
前端·javascript
零度晚风11 小时前
React 底层原理 & 新特性
前端
用户618482402195111 小时前
我受够了 Electron 的 IPC 样板代码,于是写了 electron-ipc-auto-import
前端
梦想的颜色11 小时前
TypeScript 完全指南(中):函数、接口、类与高级类型
前端·typescript
鹏多多11 小时前
OpenSpec+SDD规范驱动AI Agent开发项目实战指南
前端·vue.js·react.js
叶小树咯11 小时前
React 为什么不能像 Vue 那样 state.count++
前端·react.js