问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

HTML5新宠EventSource:快速入门指南

创作时间:
作者:
@小白创作中心

HTML5新宠EventSource:快速入门指南

引用
CSDN
12
来源
1.
https://blog.csdn.net/kandan_cc/article/details/136375724
2.
https://blog.csdn.net/gitblog_00942/article/details/141007101
3.
https://blog.csdn.net/weixin_49066399/article/details/138713416
4.
https://m.blog.csdn.net/Cike___/article/details/143627348
5.
https://developer.mozilla.org/en-US/docs/Web/API/EventSource
6.
https://www.cnblogs.com/xd502djj/p/18644869
7.
https://developer.mozilla.org/en-US/docs/Web/API/EventSource/open_event
8.
https://developer.mozilla.org/en-US/docs/Web/API/EventSource/EventSource
9.
http://xiaoyuge.work/spring-boot-sse/index.html
10.
https://developer.mozilla.org/zh-CN/docs/Web/API/Server-sent_events/Using_server-sent_events
11.
https://www.cnblogs.com/WindrunnerMax/p/18541254
12.
https://juejin.cn/post/7401011618043838474

随着Web应用的不断发展,实时通信已成为许多应用场景的核心需求。从社交媒体的实时更新到金融市场的行情推送,从在线游戏的状态同步到协作编辑的实时保存,实时通信技术正在改变我们使用互联网的方式。在众多实时通信技术中,HTML5引入的EventSource以其简单高效的特点,成为了实现服务器推送(Server-Sent Events,简称SSE)的理想选择。本文将带你从零开始,全面掌握EventSource的使用方法,让你能够快速在项目中实现高效的实时数据推送功能。

01

什么是EventSource?

EventSource是HTML5提供的一种用于实现服务器发送事件(Server-Sent Events,简称SSE)的API。它允许服务器向浏览器推送实时更新,而无需客户端轮询。与WebSocket不同,EventSource只支持单向通信,即数据只能从服务器推送到客户端,而不能从客户端发送到服务器。这种特性使得EventSource特别适合用于实现服务器到客户端的实时数据推送,如股票行情、新闻更新、社交媒体动态等场景。

02

EventSource的主要特点

  1. 单向通信:数据仅从服务器推送到客户端,不支持客户端向服务器发送数据。
  2. 自动重连:连接断开后,浏览器会自动尝试重新建立连接,无需手动处理重连逻辑。
  3. 轻量级:基于HTTP协议,相比WebSocket更简单高效,开销更小。
  4. 文本流格式:数据以纯文本的事件流格式传输,包含事件名称、数据、ID等信息。
  5. 带状态更新:通过事件ID,客户端可以恢复到断线前的状态,避免数据丢失。
03

基本使用方法

1. 创建EventSource实例

要使用EventSource,首先需要创建一个EventSource实例,传入服务器端的SSE接口URL:

const eventSource = new EventSource('/sse-endpoint');

2. 监听事件

创建实例后,可以通过监听事件来接收服务器推送的数据。主要有三种事件:

  • message事件:当服务器推送数据时触发,数据通过event.data获取。
  • open事件:当与服务器的连接成功建立时触发。
  • error事件:当连接发生错误时触发,可以用于处理重连逻辑。
eventSource.onmessage = function(event) {
  console.log('Received message:', event.data);
};

eventSource.onopen = function(event) {
  console.log('Connection opened:', event);
};

eventSource.onerror = function(event) {
  console.error('EventSource error:', event);
  // 可以在这里处理重连逻辑
};

3. 关闭连接

如果需要手动关闭连接,可以调用close方法:

eventSource.close();
04

服务端配置

服务器端需要设置响应头Content-Typetext/event-stream,并保持连接不关闭。以下是一个简单的Node.js示例:

const http = require('http');

http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  setInterval(() => {
    const message = `data: Server time: ${new Date().toLocaleTimeString()}\n\n`;
    res.write(message);
  }, 3000);
}).listen(3000, () => {
  console.log('Server running on port 3000');
});
05

高级功能

自定义请求头

原生的EventSource API不支持自定义请求头,但可以通过以下方式解决:

  1. URL参数:将参数附加到URL上传递给服务器。

    const eventSource = new EventSource('/sse-endpoint?token=12345&userId=alice');
    
  2. 使用fetch或XMLHttpRequest:创建长连接并读取响应流。

    fetch('/sse-endpoint', {
      method: 'GET',
      headers: {
        'Authorization': 'Bearer your-token-here'
      }
    })
    .then(response => response.body.getReader())
    .then(reader => {
      reader.read().then(function processText({ done, value }) {
        if (done) return;
        console.log(new TextDecoder().decode(value));
        return reader.read().then(processText);
      });
    });
    

跨浏览器兼容性

对于不支持EventSource的旧版浏览器,可以使用polyfill库:

<script src="https://unpkg.com/event-source-polyfill/src/eventsource.min.js"></script>

使用时与原生API一致:

const eventSource = new EventSourcePolyfill('/sse-endpoint');

错误处理与重连机制

EventSource具有自动重连的特性,但可以通过监听error事件来自定义重连逻辑:

eventSource.onerror = function(event) {
  console.error('EventSource error:', event);
  eventSource.close();
  setTimeout(() => {
    eventSource = new EventSource('/sse-endpoint');
  }, 5000); // 5秒后重试
};
06

实战示例

下面是一个完整的客户端和服务端代码示例,展示了EventSource在实际项目中的应用。

客户端代码

const eventSource = new EventSource('/sse-endpoint');

eventSource.onmessage = function(event) {
  console.log('Received message:', event.data);
};

eventSource.onopen = function(event) {
  console.log('Connection opened:', event);
};

eventSource.onerror = function(event) {
  console.error('EventSource error:', event);
};

服务端代码(Node.js)

const http = require('http');

http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'text/event-stream',
    'Cache-Control': 'no-cache',
    'Connection': 'keep-alive'
  });

  setInterval(() => {
    const message = `data: Server time: ${new Date().toLocaleTimeString()}\n\n`;
    res.write(message);
  }, 3000);
}).listen(3000, () => {
  console.log('Server running on port 3000');
});
07

总结

EventSource作为HTML5引入的服务器发送事件API,以其简单易用、轻量级和自动重连等特点,成为了实现Web实时通信的重要选择。通过本文的介绍,相信你已经掌握了EventSource的基本使用方法和高级功能,能够将其应用到实际项目中,为用户提供更实时、更流畅的交互体验。

虽然EventSource功能强大,但也要注意其局限性。例如,它不支持双向通信,无法从客户端向服务器发送数据;在非HTTP/2协议下,可能会受到浏览器连接数限制的影响。因此,在选择实时通信技术时,需要根据具体需求和场景进行权衡。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号