[字节青训_AI对话框]SSE交互规范、自定义事件、前后端数据传递、状态监听、连接和断开详解

news/2025/2/26 5:55:08

1.SSE基础

以下是关于 Server-Sent Events (SSE) 的前后端交互规范、常见方法及自定义扩展的完整指南:


一、SSE 交互规范

1. 基础协议
  • HTTP 协议:基于 HTTP/1.1 长连接,响应头需包含:
  Content-Type: text/event-stream
  Cache-Control: no-cache
  Connection: keep-alive
2. 数据格式规范

每条消息格式为:

[field]: value\n

支持字段:

  • data:消息内容(必填)
  • event:自定义事件类型(默认 message
  • id:消息ID(用于断线重连定位)
  • retry:重连时间(毫秒)

示例:标准数据流

event: status
{"progress": 75%}

This is a message\n
with two lines

id: 12345
retry: 5000

二、常见方法

1. 前端基础用法
const es = new EventSource('/api/stream');

// 监听默认事件
es.onmessage = ({
     data }) => console.log('Received:', data);

// 监听自定义事件
es.addEventListener('update', ({
     data }) => {
   
  console.log('Update:', JSON.parse(data));
});

// 错误处理
es.onerror = () => console.error('Connection lost');
2. 后端基础实现(Node.js)
app.get('/api/stream', (req, res) => {
   
  res.writeHead(200, {
   
    'Content-Type': 'text/event-stream',
    'Access-Control-Allow-Origin': '*' // 处理跨域
  });

  // 发送初始数据
  res.write('Connected\n\n');

  // 定时推送数据
  const timer = setInterval(() => {
   
    res.write(`${
     Date.now()}\n\n`);
  }, 1000);

  // 客户端断开时清理
  req.on('close', () => clearInterval(timer));
});

三、自定义扩展方法

1. 身份验证
  • 前端:通过 URL 参数或 Cookie 传递 Token
  new EventSource('/api/stream?token=xxxx')
  • 后端:验证 Token 有效性
  app.get('/api/stream', (req, res) => {
   
    if (!validateToken(req.query.token)) {
   
      res.writeHead(401).end();
      return;
    }
    // ...后续推送逻辑
  });
2. 结构化数据传递

使用 JSON 编码:

// 前端解析
es.onmessage = ({
     data }) => {
   
  const msg = JSON.parse(data);
  console.log(msg.type, msg.content);
};

// 后端发送
res.write(`data:${
     JSON.stringify({
      type: 'alert', content: 'Warning' })}\n\n`);
3. 分块传输大文本(流式数据处理)
// 后端分块发送
const bigText = "Very long text...";
for (const chunk of chunkText(bigText, 100)) {
    // 每100字符分块
  res.write(`event: chunk\n${
     chunk}\n\n`);
}

// 前端组装
let fullText = '';
es.addEventListener('chunk', ({
     data }) => {
   
  fullText += data;
});
4. 双向通信模拟

SSE 是单向通道,但可通过以下方式模拟双向:

// 前端通过 AJAX 发送控制命令
function sendCommand(cmd) {
   
  fetch('/api/control', {
    method: 'POST', body: cmd });
}

// 后端响应命令并推送结果
app.post('/api/control', (req, res) => {
   
  handleCommand(req.body, (result) => {
   
    sseClients.forEach(client => 
      client.res.write(`event: command-result\n${
     result}\n\n`)
    );
  });
  res.status(200).end();
});

四、高级实践

1. 性能优化
  • 压缩数据:启用 gzip 压缩
  app.use(compression()); // Express 中间件
  • 心跳检测:防止代理超时(核心,面试!!!
  setInterval(() => res.write(': ping\n\n'), 30000);
3. 错误恢复

重连,简历

let es = null;

function connectSSE() {
   
  es = new EventSource('/api/stream');
  
  es.onerror = () => {
   
    es.close();
    setTimeout(connectSSE, 5000); // 5秒后重连
  };
}

connectSSE(); // 初始连接

五、注意事项

  1. 跨域问题
    确保响应头包含 Access-Control-Allow-Origin,或通过代理解决。

  2. 连接限制
    浏览器对单个域名 SSE 连接数有限制(通常 6 个),需合理设计连接复用。

  3. 数据安全
    敏感数据需加密或通过 HTTPS 传输。

  4. 兼容性
    SSE 不支持 IE,需使用 Polyfill(如 eventsource 库)。


通过上述规范和扩展方法,SSE 可灵活应用于实时监控、消息推送、日志流等场景。开发者应根据具体需求选择合适的数据格式和通信模式。

2.前端SSE类封装

//EventSourceWrapper.js
type EventSourceConfig = {
   
  url: string;
  queryParams?: Record<string, string>;
  onMessage: (string) => void; // 直接传递数据
  onError?: (error: Error) => void;
};

export class EventSourceWrapper {
   
  private eventSource: EventSource | null = null;
  
  constructor(private 

http://www.niftyadmin.cn/n/5868115.html

相关文章

deepseek部署:ELK + Filebeat + Zookeeper + Kafka

## 1. 概述 本文档旨在指导如何在7台机器上部署ELK&#xff08;Elasticsearch, Logstash, Kibana&#xff09;堆栈、Filebeat、Zookeeper和Kafka。该部署方案适用于日志收集、处理和可视化场景。 ## 2. 环境准备 ### 2.1 机器分配 | 机器编号 | 主机名 | IP地址 | 部署组件 |-…

WIFI的SSID超长,隐藏,重复 (2.4G和5G差异)

目录 1、2.4G和5G的频率范围‌ 2、2.4G和5G的差异‌&#xff1a; 3、隐藏ssid显示为\x00 4、 重复的ssid名称 扩展 前言 最近处理wifi设备时发现&#xff0c;小小一个ssid就有超多的问题。 不是中文转义就是超长&#xff0c;现在还发现空字符的&#xff0c;原来时对方路由隐藏了…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.1.1对比传统数据库与搜索引擎(MySQL vs ES)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 为什么选择Elasticsearch&#xff1f;——从MySQL到Elasticsearch的深度对比引言一、核心概念对比1. 数据模型差异2. 查询语言对比 二、适用场景对比1. MySQL的典型场景2. E…

CPU多级缓存机制

目录 一、前置知识 ---- CPU的核心 1.1. 单核与多核CPU 二、CPU多级缓存机制 三. 缓存的基本结构/缓存的存储结构 四、CPU缓存的运作流程/工作原理 五、CPU多级缓存机制的工作原理【简化版】 5.1. 缓存访问的过程 (5.1.1) L1缓存&#xff08;一级缓存&#xff09;访问 …

Nginx的安装和部署以及Nginx的反向代理与负载均衡

Nginx的安装和部署以及Nginx的反向代理与负载均衡 1. 本文内容 Nginx的安装Nginx的静态网站部署Nginx的反向代理与负载均衡&#xff0c;配置反向代理与负载均衡 2. Nginx的安装与启动 2.1 什么是Nginx Nginx是一款高性能的http服务器/反向代理服务器及电子邮件&#xff08…

Room记录搜索记录逻辑思路

记录数据使用ROOM&#xff0c;传递使用ViewModel LiveDataBus,这篇文章主要记录 搜索记录 本地 线上&#xff0c;上传失败&#xff0c;记录本地&#xff0c;网络回复统一上传等逻辑的操作。 目录 首先是设计数据表&#xff1a; 定义DAO操作接口 定义数据库类 Mvvm 模式中封…

监听其他音频播放时暂停正在播放的音频

要实现当有其他音频播放时暂停当前音频&#xff0c;你可以使用全局事件总线或 Vuex 来管理音频播放状态。这里我将展示如何使用一个简单的事件总线来实现这个功能。 首先&#xff0c;你需要创建一个事件总线。你可以在项目的一个公共文件中创建它&#xff0c;例如 eventBus.js…

flutter: table calendar笔记

pub dev&#xff1a;table_calendar 3.2.0 我来详细解释 TableCalendar 是如何根据不同的 CalendarFormat 来显示界面的。主要逻辑在 CalendarCore 中实现。 核心逻辑分为以下几个部分&#xff1a; 页面数量计算 - _getPageCount 方法根据不同格式计算总页数&#xff1a; in…