SSE(Server-Sent Events)是一种服务器推送技术,用于在不刷新页面的情况下将实时更新的数据推送到客户端。相比于传统的轮询和长轮询方式,SSE 可以节省网络流量和服务器资源,并提供更快的响应速度和更佳的用户体验。本文将介绍在 Java 中实现 SSE 技术的解决方案,并提供详细的代码示例和指导意义。
1. SSE 技术基础
SSE 是基于 HTTP 协议的一种技术,通过在客户端打开一个持久化的 HTTP 连接,服务器可以推送任意数量的数据到客户端。SSE 的主要特点如下:
- SSE 默认使用 HTTP/1.1 协议,不需要像 WebSocket 一样创建新的协议。
- SSE 使用 GET 请求打开一个持久化的 HTTP 连接,服务器可以在该连接中推送数据。
- SSE 推送的数据以文本形式返回,每条数据以“data:”开头,“\n\n”结尾。
- SSE 允许服务器设置事件的名称(可选),客户端可以根据事件名称订阅特定的事件。
- SSE 支持自定义的事件类型和消息 ID,以及服务器端和客户端断开连接的处理方式。
2. 实现 SSE 服务器端
在 Java 中实现 SSE 服务器端可以使用 Servlet 和 Jersey 等框架。下面是使用 Spring Boot + Servlet 的 SSE 服务器端的代码示例:
-- -------------------- ---- ------- --------------- ------ ----- ------------- - ------------------------- ------------------------------------------- ------ ----------------------------- ----- - ------ ------------------------------------ ------------- -- --------------------------------- ----------------- ----------------------------- ------------- ------ ---------- - -
注解 @GetMapping 用于映射 HTTP GET 请求,值为 "/sse",MediaType.TEXT_EVENT_STREAM_VALUE 指定返回值类型为 text/event-stream,表示是 SSE 数据格式。方法 sse() 返回一个 Flux,表示 SSE 持久连接中推送的数据流。在该示例中,每秒钟推送一条数据,包含事件名称("message")、消息 ID(当前时间戳)、文本数据("Hello, SSE!")。
3. 实现 SSE 客户端
在浏览器中实现 SSE 客户端可以使用 JavaScript 原生 API 或第三方库(如 EventSource.js)。下面是使用原生 API 的 SSE 客户端的代码示例:
const source = new EventSource('/sse'); source.addEventListener('message', function(event) { console.log('data: ' + event.data); }, false);
使用 EventSource 构造函数创建一个新的 SSE 连接,值为 "/sse",也就是 SSE 服务器端的 URL。使用 addEventListener 方法监听事件名称为 "message" 的事件,当服务器向客户端推送消息时触发该事件,并打印该消息的文本数据。
4. 实现 SSE 应用场景
SSE 技术可以用于多种实时数据更新的应用场景,如在线聊天、股票行情、天气预报、地图标注、进度条更新等。下面以在线聊天室为例,介绍 SSE 技术的应用。
-- -------------------- ---- ------- --------------- ------ ----- -------------- - ------- ----- --------------------------------- -------- - --- ------------------------- --------------------- ------ ---------- ----------------- ------ -------- - --- ---------------------------- ---- - --------- - ------------------------------------------- ----------------- -------------- ---------- - ------ ------------- - -------------------------- ------------------------------------------- ------ ----------------------------- --------------------------------- --------- - ----------------------------------------------------------- -------------------------------------------------- ---------------------------------------------- ------ --------------------------- ---- - ------------------------------------------- -- - ---------------------- --- ------------------- ------ -------------- - -
ChatController 类定义了一个聊天室的 SSE 接口,包括发送和接收两个方法。发送方法用于将消息发送到所有已连接的客户端,接收方法用于接收客户端发送的消息,并发送到所有的客户端。在接收方法中,使用 response 对象的 setContentType 方法设置响应类型为 text/event-stream,getHeaders 方法设置 Cache-Control 为 no-cache,X-Accel-Buffering 为 no,表示不缓存连接和数据,避免数据延迟和丢失。使用 Sinks 对象的 many().unicast() 方法创建一个服务器端的 SSE 端点,用于接收客户端的 SSE 持久连接,并返回 Flux 对象,表示 SSE 数据流。使用 ServerSentEventSink 对象的 send 方法将接收到的消息发送到所有的 SSE 客户端,使用 onDispose 方法在客户端断开连接时取消 SSE 端点。
在前端界面上,使用 HTML、CSS 和 JavaScript 的组合可以实现一个基本的聊天室界面。下面是一个简单的聊天室界面示例:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- ----------- ------------ ------ ---------------- ------------ - ------- --- ----- ----- ------- ----- -------- ----- ------- ------ ----------- ----- - ----------- - ------- ----- - -------- ------- ------ ---- ----------------------- ---- ---------------- ------ ----------- ---------------- ------- ------------------------------ ------ ------- ----------------------- ----- ----------- - --- --------------------- ----- ---------- - --------------------------------------- --------------------------------------- --------------- - ----- ------- - ----------------------- ----- -------- - -------------------------------------- ----- - - ---------------------------- -- ------------ - ---- - ----------- - ------------------------ -------------------------- -- ------- ----- --------- - -------------------------------------- ----- ---------- - --------------------------------------- ------------------ - ---------- - ----- ------- - ---------------- --------------- - --- -------------- - ------- ------- -------- - --------------- ------------ -- ----- ------- --- -- --------- ------- -------
界面中包括一个聊天窗口和一个消息输入框。使用 EventSource 构造函数创建一个 SSE 连接,并在接收到消息时添加一个段落元素,用于显示消息的文本。使用 fetch 函数将输入框的消息发送到服务器端,并清空输入框。
5. 总结
本文介绍了 SSE(Server-Sent Events)技术的基础知识、服务器端的实现方案和客户端的实现方案,并以在线聊天室为例,说明了 SSE 技术的应用场景。使用 SSE 技术可以轻松地实现实时数据更新的功能,提高应用的响应速度和用户体验。在实际开发中,建议使用成熟的框架和工具,如 Spring Boot、Netty、Node.js、WebSocket、Socket.IO 等,可以大大简化代码编写和维护的难度。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649910ca48841e9894604ed3