SSE初探

SSE(Server-Sent Events)是一种服务器推送技术,答应服务器经过HTTP衔接向客户端主动发送更新。它描绘了服务器在建立初始客户端衔接后怎么向客户端建议数据传输。SSE通常用于向浏览器客户端发送音讯更新或连续数据流,并经过名为EventSource的JavaScript API来增强原生、跨浏览器的流式传输。

SSE的历史: SSE机制最早由Ian Hickson在2004年的“WHATWG Web Applications 1.0”提案中指定。2006年9月,Opera浏览器在一个名为“Server-Sent Events”的试验性功用中完成了这项技术。

浏览器支撑: 一切现代浏览器都支撑Server-Sent Events:Firefox 6 、Google Chrome 6 、Opera 11.5 、Safari 5 、Microsoft Edge 79 。

SSE的优势:

  1. 简略易用:SSE运用标准的HTTP协议,无需特别的协议或服务器完成即可作业。
  2. 单向通讯:SSE供给了一种单向的服务器到客户端的通讯方式,适用于那些只需求服务器向客户端发送更新的场景。
  3. 主动重连:当衔接关闭时,浏览器会主动测验从头衔接服务器,无需手动处理衔接问题。
  4. 事情标识:SSE支撑给事情附加唯一的标识符,能够帮助浏览器在衔接断开后确定应该触发哪个事情。
  5. 多行数据:SSE支撑发送多行数据,能够便利地发送JSON等杂乱数据格式。

SSE的用处: SSE适用于许多实时更新的场景,例如:

  • 实时新闻更新
  • 股票行情推送
  • 地图上的位置盯梢
  • 社交媒体的实时通知
  • 在线聊天应用等

但咱们这儿想要聊的 SSE 的最核心的用处在于,AI聊天的推送,也就是为什么它能够一段一段的发送,而不必等悉数完毕再发送。

怎么完成?

咱们完成 SSE 能够经过 fetch 和 EventSource 的方式。

fetch 完成

咱们先来聊聊 fetch 的完成

const endpoint = 'http://example.com/sse';
fetch(endpoint, {
  headers: { 'Accept': 'text/event-stream' },
}).then(response => {
  const reader = response.body.getReader();
  let buffer = '';
  reader.read().then(function process({ done, value }) {
    if (done) {
      console.log('Stream closed');
      return;
    }
    buffer  = new TextDecoder('utf-8').decode(value);
    const lines = buffer.split('n');
    buffer = lines.pop();
    lines.forEach(line => {
      console.log(line);
    });
    // Continue reading
    return reader.read().then(process);
  });
}).catch(error => {
  console.error(error);
});

fetch() 的长处:

  1. 更灵敏的数据处理:运用 fetch() 办法能够更灵敏地处理 SSE 数据流,由于咱们能够运用 JavaScript 中的任何办法来处理和解析从 SSE 服务器端点接纳的数据流。

  2. 更高的兼容性:fetch() 办法是一个标准的 Web API,支撑一切主流的现代浏览器。

  3. 更好的操控权:运用 fetch() 办法能够更好地操控 SSE 数据流的读取和处理。咱们能够手动操控 SSE 数据流的读取进展,而不是依赖于 EventSource 目标的主动操控。

fetch() 的缺陷:

  1. 需求手动解析数据:运用 fetch() 办法需求手动解析从 SSE 服务器端点接纳的数据流,这需求一些额外的代码和技术。

  2. 无法主动重连:运用 fetch() 办法无法主动重连 SSE 服务器端点。假如与 SSE 服务器端点的衔接断开,咱们需求手动从头衔接。

  3. 无法处理过错:运用 fetch() 办法无法处理 SSE 数据流的过错。假如产生过错,咱们需求手动处理并调试代码。

EventSource 的完成

const endpoint = 'http://example.com/sse';
const eventSource = new EventSource(endpoint);
eventSource.addEventListener('open', event => {
  console.log('Connected to SSE server');
});
eventSource.addEventListener('message', event => {
  console.log(event.data);
});
eventSource.addEventListener('error', error => {
  console.error(error);
});
setTimeout(() => {
  eventSource.close();
  console.log('Connection closed');
}, 60000);

EventSource 的长处:

  1. 主动重连:EventSource 目标供给了主动重连的功用。假如与 SSE 服务器端点的衔接断开,EventSource 目标会主动测验从头衔接,并恢复之前的数据流。

  2. 主动解析数据:EventSource 目标主动解析从 SSE 服务器端点接纳的数据流,并将其转换为 JavaScript 目标,便利咱们进行处理和操作。

  3. 过错处理:EventSource 目标供给了过错处理的功用。假如产生过错,EventSource 目标会触发过错事情,并供给过错信息,便利咱们进行调试和处理。

EventSource 的缺陷:

  1. 低兼容性:EventSource 目标是一个 HTML5 新增的 Web API,可能不被一切的浏览器所支撑。一些旧版的浏览器可能不支撑 EventSource 目标。

  2. 可能会呈现内存走漏:运用 EventSource 目标可能会呈现内存走漏的问题,特别是在长期运行的情况下。因而,咱们需求注意开释 EventSource 目标。

后话

咱们既能够自己用原生的完成方式,还能够用别人封好的工具库,比方@rangermauve/fetch-event-source

SSE 本质上其实还是属于 HTTP 恳求,只是经过添加了accept: ‘text/event-stream’,将传输进程转化成了“流”的形式。

那么这就是本篇文章的悉数内容啦