自学内容网 自学内容网

Spring Boot整合SSE实时通信

服务器发送事件(Server-Sent Events, SSE)是一种让网页实时更新的技术。想象一下,您正在浏览一个网页,而这个网页需要在有新信息时自动更新,比如新闻网站的最新消息、社交媒体的通知或股票市场的价格变动。SSE使得这种实时更新成为可能,并且它是通过普通的HTTP连接实现的,这意味着它不需要任何特殊的协议或复杂的设置。

SSE的主要特点

  • 基于HTTP:SSE使用标准的HTTP协议来通信,因此它很容易集成到现有的网络架构中,无需额外配置。

  • 单向数据流:与WebSocket不同,SSE只允许服务器向客户端推送数据,而不能反过来。这对于只需要从服务器接收更新的场景非常有用,例如直播评论或通知提醒。

  • 自动重连:如果由于某种原因连接中断了,浏览器会自动尝试重新连接到服务器,确保用户不会错过任何更新。

  • 自定义事件类型:除了基本的数据推送外,SSE还允许服务器发送特定类型的事件,这样客户端就可以根据不同的事件类型做出相应的反应。

  • 轻量级和简单:相比其他如WebSocket等技术,SSE的实现更为简单,适合不需要双向通信的应用场景。对于开发者来说,这意味着更少的代码和更容易维护的系统。

添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

创建SSE控制器

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
@CrossOrigin
@RestController
@RequestMapping("sse")
public class SseController {
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    @GetMapping("/handleSse")
    public SseEmitter handleSse() {
        SseEmitter emitter = new SseEmitter();
        executorService.execute(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    emitter.send(SseEmitter.event().name("message").data("数据库来消息了" + i));
                    Thread.sleep(1000);
                }
                emitter.complete();
            } catch (IOException | InterruptedException e) {
                emitter.completeWithError(e);
            }
        });
        return emitter;
    }
}

客户端实现

<!DOCTYPE html>
<html>
<body>
<h1>SSE Demo</h1>
<div id="messages"></div>
<button id="connectButton">连接</button>
<button id="disconnectButton" disabled>断开连接</button>

<script>
    let eventSource = null;
    const messages = document.getElementById('messages');
    const connectButton = document.getElementById('connectButton');
    const disconnectButton = document.getElementById('disconnectButton');

    function connect() {
        if (eventSource) return; // 如果已经连接,则不重复创建

        eventSource = new EventSource('http://localhost:8081/items/handleSse');

        eventSource.onmessage = function(event) {
            const message = document.createElement('p');
            message.textContent = event.data;
            messages.appendChild(message);
        };

        eventSource.onerror = function(error) {
            console.error('EventSource failed:', error);
            disconnect(); // 在发生错误时也尝试断开连接
        };

        // 禁用连接按钮,启用断开连接按钮
        connectButton.disabled = true;
        disconnectButton.disabled = false;
    }

    function disconnect() {
        if (!eventSource) return; // 如果没有连接,则不执行任何操作

        eventSource.close();
        eventSource = null;

        // 启用连接按钮,禁用断开连接按钮
        connectButton.disabled = false;
        disconnectButton.disabled = true;
    }

    // 给按钮添加事件监听器
    connectButton.addEventListener('click', connect);
    disconnectButton.addEventListener('click', disconnect);
</script>
</body>
</html>

SSE(服务器发送事件)的优缺点及适用场景

优点
  • 简单易用:与WebSocket相比,SSE不需要复杂的握手过程。它的API设计直观,开发者可以更快速地上手。
  • 广泛的浏览器支持:几乎所有现代浏览器都支持SSE,包括手机和平板上的浏览器,这意味着它几乎可以在任何设备上工作。
  • 高效能和低延迟:相较于传统的轮询方式,SSE减少了不必要的请求次数,降低了服务器负担,并提高了数据更新的速度。
  • 自动重连功能:当网络连接中断时,浏览器会自动尝试重新连接到服务器,这简化了开发者的代码。
缺点
  • 单向通信限制:SSE只允许服务器向客户端推送信息,如果需要从客户端向服务器发送数据,则必须使用其他方法或技术。
  • 依赖HTTP长连接:虽然SSE优化了数据传输,但它的实现仍然基于HTTP连接,这可能在网络条件不佳或者通过某些代理服务器时遇到问题。
适用场景

SSE非常适合用于那些只需要服务器向客户端推送实时更新的应用场景,例如:

  • 实时新闻更新
  • 股票价格变动通知
  • 社交媒体动态提醒
  • 实时评论流
  • 系统状态监控
SSE vs. 轮询 vs. WebSocket
  • SSE与轮询的区别:传统轮询是客户端定时询问服务器是否有新数据,这种方式不仅增加了服务器的压力,也带来了较高的延迟。而SSE让服务器在有新数据时主动推送给客户端,减少了不必要的请求,提升了性能和用户体验。

  • SSE与WebSocket的对比

    • 通信方向:WebSocket支持双向通信,意味着客户端和服务器都可以随时发送消息;而SSE仅允许服务器向客户端推送信息。
    • 协议基础:WebSocket使用了自己的协议,而SSE基于标准的HTTP/HTTPS协议,使得SSE更容易部署并且更易于调试。
    • 连接管理:WebSocket建立后保持连接开放,直到被显式关闭;而SSE会在每次事件推送后自然断开,然后根据需要重新建立连接。
    • 兼容性和安全性:由于SSE基于HTTP协议,因此它在网络穿越方面表现得更好,并且能够更好地利用现有的安全机制(如HTTPS)。
选择建议
  • 轮询:适合于对实时性要求不高、只需要偶尔检查更新的场景。不过,这种方式会增加服务器的负载。
  • SSE:对于需要实时推送更新但不涉及双向通信的应用来说,SSE是一个很好的选择,因为它实现简单,而且浏览器兼容性好。
  • WebSocket:适用于需要频繁双向通信的应用,比如在线聊天室或多人在线游戏。

总之,选择哪种技术取决于您的具体需求和技术栈。如果您只需要服务器向客户端推送信息,并希望实现起来尽可能简单,那么SSE可能是最佳的选择。


原文地址:https://blog.csdn.net/weixin_45916098/article/details/145047974

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!