使用 new EventSource 实现前端实时通信

示例:

eventSource单向通信

1. 什么是 EventSource?

EventSource 是浏览器提供的一种实现服务器推送(Server-Sent Events,简称 SSE)功能的 API。它是基于 HTTP 协议的单向通信机制,可以通过服务器将实时数据推送到客户端,而不需要客户端不断发起请求。

与传统的 AJAX 请求(如 XMLHttpRequest 或 fetch)不同,EventSource 会创建一个长连接,允许服务器主动向浏览器推送数据。这使得前端可以高效地接收实时数据,而不必通过轮询来获取更新。

为什么使用 EventSource?

  • 实时性强:可以在服务器有更新时即时推送数据,而不需要客户端不断请求。
  • 低延迟:相比于轮询,EventSource 更加高效,因为它不会不断地向服务器发起 HTTP 请求。
  • 简洁的 API:EventSource 的用法非常简洁,只需要一行代码即可实现连接,并且可以轻松处理服务器推送的数据。

2. EventSource 的基本用法

EventSource 是通过 new EventSource(url) 创建的,参数 url 是服务器端提供的推送数据的接口。服务器会向客户端推送实时数据,并以 text/event-stream 格式传输。

基本语法

const eventSource = new EventSource('your-server-endpoint');

监听服务器发送的事件
EventSource 提供了几个事件来监听服务器端推送的消息:

  • message:默认事件,接收到消息时触发。
  • open:连接成功时触发。
  • error:连接出错时触发。

示例代码
假设我们有一个服务器端接口 /events,该接口会定期向客户端推送消息。

// 创建 EventSource 实例
const eventSource = new EventSource('/events');// 监听连接成功事件
eventSource.addEventListener('open', function(event) {console.log('连接已成功建立');
});// 监听消息事件
eventSource.addEventListener('message', function(event) {console.log('收到消息:', event.data);
});// 监听连接出错事件
eventSource.addEventListener('error', function(event) {if (event.eventPhase == EventSource.CLOSED) {console.log('连接已关闭');} else {console.log('发生错误:', event);}
});

代码解析:

  • new EventSource(‘/events’):创建与服务器的连接,/events 是服务器端的推送接口。
  • eventSource.addEventListener(‘message’, callback):监听 message 事件,callback 会在接收到推送消息时执行,event.data 包含服务器发送的消息内容。
  • eventSource.addEventListener(‘open’, callback):监听连接成功事件,当连接成功时会调用此回调函数。
  • eventSource.addEventListener(‘error’, callback):监听错误事件,如果连接失败或被关闭,会触发该事件。

3. 服务器端的实现

在服务器端,我们需要将数据按 text/event-stream 的格式发送给客户端,通常使用一种流式的方式将数据传输给浏览器。以下是一个用 Node.js 和 Express 实现的简单 SSE 服务器示例:

const express = require('express');
const app = express();app.get('/events', (req, res) => {res.setHeader('Content-Type', 'text/event-stream');res.setHeader('Cache-Control', 'no-cache');res.setHeader('Connection', 'keep-alive');let count = 0;setInterval(() => {count++;res.write(`data: 这是第 ${count} 条实时消息\n\n`);}, 1000);
});app.listen(3000, () => {console.log('服务器正在监听端口 3000');
});

代码解析:
res.setHeader(‘Content-Type’, ‘text/event-stream’):告诉浏览器返回的是一个事件流。
setInterval():每隔 1 秒推送一次消息,模拟服务器实时推送数据给客户端。
启动服务器并访问
启动服务器:node server.js
在浏览器中打开前端页面,监听来自 /events 接口的数据。

4. EventSource 的高级用法

自定义事件
在 SSE 中,客户端可以根据需要使用自定义事件来处理不同类型的数据,而不仅仅是 message 事件。可以使用 event 属性来定义自定义事件。

代码示例:

// 服务器端
res.write('event: customEvent\n');
res.write('data: 这是一个自定义事件\n\n');// 客户端
eventSource.addEventListener('customEvent', function(event) {console.log('收到自定义事件:', event.data);
});

自动重连
EventSource 会在连接断开后自动重连,默认重连时间为 3 秒,可以通过设置 retry 属性来指定自定义的重连时间。
代码示例:

// 服务器端
res.write('retry: 5000\n');  // 重连时间为 5000 毫秒(5秒)

关闭连接
在前端代码中,可以使用 eventSource.close() 来主动关闭连接。

eventSource.close();

5. EventSource 与其他通信技术的比较

与 WebSocket 的对比
EventSource 和 WebSocket 都可以实现服务器向客户端的实时数据推送,但它们有不同的适用场景:

  • EventSource:是单向通信,适合用来从服务器向客户端推送数据,比如实时通知、新闻更新等。
  • WebSocket:是双向通信,适合需要客户端和服务器之间进行双向交互的场景,如在线聊天、实时协作等。

与轮询的对比
轮询是通过定时向服务器发送请求获取最新的数据,缺点是每次都需要发起 HTTP 请求,带来不必要的开销。而 EventSource 是建立一个持久连接,服务器主动推送数据,避免了频繁的 HTTP 请求。

6. 总结

EventSource 提供了一种简单、有效的方式来实现服务器推送数据到前端。与传统的轮询相比,它能够减少请求开销,提高实时性。它也比 WebSocket 更容易实现和使用,适合单向数据流的应用场景。

优点:

  • 实现简单。
  • 低延迟,适合实时通知等应用。
  • 自动重连功能,保证连接的稳定性。

缺点:

  • 只支持单向通信,不能用于需要双向通信的场景(此时可以选择 WebSocket)。
  • 浏览器支持较为有限,虽然现代浏览器普遍支持,但在一些老旧浏览器中可能无法使用。

通过使用 EventSource,开发者可以轻松地在 Web 应用中实现实时数据流功能,为用户提供更好的交互体验。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Input——查找并添加目标窗口(七)

在 Android 输入系统中,InputDispatcher 的核心职责之一是将输入事件正确地传递到目标窗口。上一篇文章我们介绍到 InputDispatcher 事件分发调用到 findFocusedWindowTargetsLocked() 函数查找焦点窗口,并将焦点窗口添加到目标窗口,这里我们继续往下看。 一、获取焦点窗口…

Spring Boot中Spring MVC相关配置的详细描述及表格总结

以下是Spring Boot中Spring MVC相关配置的详细描述及表格总结: Spring MVC 配置项详解 1. 异步请求配置 spring.mvc.async.request-timeout 描述:设置异步请求的超时时间(单位:毫秒)。默认值:未设置&…

HTTP GET 和 POST 请求有什么区别

HTTP 的 GET 和 POST 请求是两种常见的 HTTP 请求方法,它们有不同的特点和应用场景。以下是它们的主要区别: 1. 用途 GET:用于从服务器获取数据或资源。GET 请求会附带查询参数在 URL 中,通常用于请求数据,如加载网页…

从入门到精通【MySQL】 联合查询

文章目录 📕摘要📕1. 多表联合查询时MySQL内部原理✏️1.1 实例:一个完整的联合查询过程 📕2. 内连接📕3. 外连接📕4. 自连接📕5. 子查询✏️5.1 单行子查询✏️5.2 多行子查询✏️5.3 多列子查…

高可用之战:Redis Sentinal(哨兵模式)

参考:Redis系列24:Redis使用规范 - Hello-Brand - 博客园 1 背景 在我们的《Redis高可用之战:主从架构》篇章中,介绍了Redis的主从架构模式,可以有效的提升Redis服务的可用性,减少甚至避免Redis服务发生完…

加密≠安全:文件夹密码遗忘背后的数据丢失风险与应对

在数字化时代,保护个人隐私和数据安全变得尤为重要。许多人选择对重要文件夹进行加密,以防止未经授权的访问。然而,一个常见且令人头疼的问题也随之而来——文件夹加密密码遗忘。当你突然发现自己无法访问那些加密的文件夹时,那种…

WPS宏开发手册——附录

目录 系列文章7、附录 系列文章 使用、工程、模块介绍 JSA语法 JSA语法练习题 Excel常用Api Excel实战 常见问题 附录 7、附录 颜色序列:在excel中设置颜色,只能设置颜色序号,不能直接设置rgb颜色 1、黑色 (Black)…

C++基础精讲-02

文章目录 1.C/C申请、释放堆空间的方式对比1.1C语言申请、释放堆空间1.2C申请、释放堆空间1.2.1 new表达式申请数组空间 1.3回收空间时的注意事项1.4malloc/free 和 new/delete 的区别 2.引用2.1 引用的概念2.2 引用的本质2.3 引用与指针的联系与区别2.4 引用的使用场景2.4.1 引…

Spring Boot MongoDB 分页工具类封装 (新手指南)

Spring Boot MongoDB 分页工具类封装 (新手指南) 目录 引言&#xff1a;为何需要分页工具类&#xff1f;工具类一&#xff1a;PaginationUtils - 简化 Pageable 创建 设计目标代码实现 (PaginationUtils.java)如何使用 PaginationUtils 工具类二&#xff1a;PageResponse<…

MyBatis的缓存、逆向工程、使用PageHelper、使用PageHelper

一、MyBatis的缓存 缓存&#xff1a;cache 缓存的作用&#xff1a;通过减少IO的方式&#xff0c;来提高程序的执行效率。 mybatis的缓存&#xff1a;将select语句的查询结果放到缓存&#xff08;内存&#xff09;当中&#xff0c;下一次还是这条select语句的话&#xff0c;直…

java中的JNI调用c库

1. 简单demo 如果是在某个项目中有包名就需要自己找ai问问去改写下cmd命令去编译执行等 java文件&#xff08;HelloJNI.java&#xff09; public class HelloJNI {// 声明 native 方法public native void sayHello();// 加载本地库static {System.loadLibrary("hello&quo…

人工智能:GPT技术应用与未来展望

GPT(Generative Pre-trained Transformer)作为自然语言处理领域的代表性技术,近年来在各行业的实际应用中展现出广泛潜力。结合其技术特性与行业需求,以下是GPT的主要应用场景、案例分析及未来挑战的总结: 一、核心应用领域与案例 文本生成与内容创作 自动化内容生产:GPT…

前端笔记-ECMAScript语法概览

更多详细可以查看1.1 ES6 教程 | 菜鸟教程 这里我将大概记录ES与JS大概不一样的部分&#xff0c;方便联合记忆。 历史与关系 ECMAScript&#xff1a;是一种由 Ecma 国际组织制定的脚本语言规范&#xff0c;它是 JavaScript 的标准化版本。ECMAScript 为 JavaScript 提供了语…

操作主机的管理

1.在AD林范围内&#xff0c;有哪几个操作主机角色 架构主机&#xff08;Schema Master&#xff09; 功能&#xff1a;负责整个AD林中所有对象和属性的定义&#xff0c;是唯一可以更新目录架构的DC。架构更新会从架构主机复制到目录林中的所有其他域控制器。 作用范围&#xf…

【Linux】网络编程

目录 端口号 网络字节序 socket编程 接口 sockaddr结构 udp网络程序 创建套接字 绑定 接收 发送 客户端需要绑定吗&#xff1f; 客户端执行方法 本地环回地址 终端文件 代码 tcp网络程序 SOCK_STREAM 监听 查询网络信息 获取新连接 地址转换函数 客户端绑…

Go 语言中的select是做什么的

Go 语言中的 select 是做什么的 在 Go 语言中&#xff0c;select 语句是用于处理多个通道&#xff08;channel&#xff09;操作的一种控制结构。它类似于 switch 语句&#xff0c;但专门用于并发编程&#xff0c;允许 Goroutine 在多个通道上等待操作&#xff08;发送或接收&a…

智慧班牌系统解决方案,SaaS智慧电子班牌云平台

智慧班牌系统解决方案 系统概述 智慧班牌是智慧校园建设不断发展的产物&#xff0c;是教育信息化改革的载体。通过智慧班牌可以高效便捷传递各种知识信息和通知信息、及时反馈课堂信息、实现班级的透明化管理。智慧班牌将学生平安考勤、异常出勤情况及时反馈至家长、老师&…

利用大模型和聚类算法找出 Excel 文件中重复或相似度高的数据,并使用 FastAPI 进行封装的详细方案

以下是一个利用大模型和聚类算法找出 Excel 文件中重复或相似度高的数据,并使用 FastAPI 进行封装的详细方案: 方案流程 数据读取:从 Excel 文件中读取数据。文本向量化:使用大模型将文本数据转换为向量表示。聚类分析:运用聚类算法对向量进行分组,将相似度高的数据归为…

【Docker基础】容器技术详解:生命周期、命令与实战案例

文章目录 一、什么是容器&#xff1f;二、为什么需要容器三、容器的生命周期容器状态容器OOM容器异常退出容器异常退出容器暂停 四、容器命令命令清单详细介绍 五、容器操作案例容器的状态迁移容器批量操作容器交互模式attached 模式detached 模式interactive 模式 容器 与 宿主…

Laravel 实现 队列 发送邮件功能

一. 什么是队列 在构建 Web 应用程序时&#xff0c;你可能需要执行一些任务&#xff0c;例如解析文件&#xff0c;发送邮件&#xff0c;大量的数据计算等等&#xff0c;这些任务在典型的 Web 请求期间需要很长时间才能执行。 庆幸的是&#xff0c;Laravel 可以创建在后台运行…