Java 中实现 SSE(Server-Sent Events)技术的解决方案

阅读时长 9 分钟读完

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 客户端的代码示例:

使用 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

纠错
反馈