开发者

Spring SseEmitter 系统及作用详细讲解

目录
  • SpringSseEmitter系统详细讲解
    • 一、SSE 基本概念(Server-Sent Events)
      • 示例(前端代码)
    • 二、Spring 的SseEmitter作用
      • 三、基本用法
        • 1. 添加依赖(Spring Boot Web 项目一般已包含)
        • 2. 控制器定义 SSE 接口
      • 四、SseEmitter 的重要方法
        • 五、注意事项
          • 1. Content-Type
          • 2. 浏览器自动重连机制
          • 3. 多用户支持
        • 六、典型应用场景
          • 七、SseEmitter 与 WebSocket 的对比
            • 八、SseEmitter 高级技巧
              • ✅ 自定义事件名称
              • ✅ 定时心跳保持连接
            • 九、总结

            SpringSseEmitter系统详细讲解

            一、SSE 基本概念(Server-Sent Events)

            • SSE 是 html5 提出的标准。
            • 客户端通过 EventSource 向服务端发起 一个长连接,服务器通过该连接持续向客户端发送事件。
            • 相比 WebSocket(双向通信),SSE 是单向的:服务端 → 客户端
            • 本质上是基于 HTTP 协议的长连接

            示例(前端代码)

            const编程客栈 eventSource = new EventSource("/sse/subscribe");
            eventSource.onmessage = function(event) {
                console.log("收到消息:", event.data);
            };
            eventSource.onerror = function(e) {
                console.error("连接错误", e);
            };

            二、Spring 的SseEmitter作用

            Spring 提供了 SseEmitter 类来简化 SSE 的开发,它本质上是一个 Controller 的返回对象,用于不断地往前端推送数据。

            三、基本用法

            1. 添加依赖(Spring Boot Web 项目一般已包含)

            <!-- Maven 中无需额外添加,spring-boot-starter-web 已包含 -->

            2. 控制器定义 SSE 接口

            @RestController
            public class SseController {
                @GetMapping("/sse/subscribe")
                public SseEmitter subscribe() {
                    SseEmitter emitter = new SseEmitter(0L); // 不超时,或设置时间,如30_000L
                    Executors.newS编程客栈ingleThreadExecutor().submit(() -> {
                        try {
                            for (int i = 1; i <= 5; i++) {
                                emitter.send("第 " + i + " 条消息");
                                Thread.sleep(1000);
                            }
                            emitter.complete(); // 关闭连接
                        } catch (Exception e) {
                            emitter.completeWithError(e);
                        }
                    });
                    return emitter;
                }
            }

            四、SseEmitter 的重要方法

            方法说明python
            send(Object data)向客户端发送消息,支持字符串、jsON 等
            send(Object data, MediaType mediaType)指定 MIME 类型发送
            complete()正常关闭连接
            completeWithError(Throwable ex)异常关闭连接
            onCompletion(Runnable callback)设置连接关闭的回调
            onTimeout(Runnable callback)设置超时回调
            onError(Consumer<Throwable> callphpback)设置错误回调
            setTimeout(long timeout)设置连接超时时间(默认 30 秒)

            五、注意事项

            1. Content-Type

            Content-Type: text/event-stream

            Spring 会自动设置,只需:

            @GetMapping(value = "/sse/subscribe", produces = MediaType.TEXT_EVENT_STREAM_VALUE)

            2. 浏览器自动重连机制

            • 如果服务端关闭连接(未调用 .complete()),浏览器会默认自动尝试重新连接。
            • 禁止客户端重连可发送 retry: 0

            3. 多用户支持

            private final Map<String, SseEmitter> userEmitters = new ConcurrentHashMap<>();
            @GetMapping("/subscribe/{userId}")
            public SseEmitter subscribe(@PathVariable String userId) {
                SseEmitter emitter = new SseEmitter(60_000L);
                userEmitters.put(userId, emitter);
                emitter.onCompletion(() -> userEmitters.remove(userId));
                emitter.onTimeout(() -> userEmitters.remove(userId));
                return emitter;
            }
            public void sendToUser(String userId, String message) throws IOException {
                SseEmitter emitter = userEmitters.get(userId);
                if (emitter != null) {
                    emitter.send(message);
                }
            }

            六、典型应用场景

            • 实时进度条
            • 实时通知系统
            • 日志推送
            • 后台任务结果反馈

            七、SseEmitter 与 WebSocket 的对比

            比较项SSE(SseEmitter)WebSocket
            通信方向单向(服务端 → 客户端)双向
            协议HTTPws:// 或 wss://
            浏览器支持广泛支持广泛支持
            实现复杂度简单需要管理连接
            使用场景实时推送聊天、游戏等

            八、SseEmitter 高级技巧

            ✅ 自定义事件名称

            emitter.send(SseEmitter.event()
                .name("customEvent")
                .data("这是自定义事件")
            );

            前端监听:

            eventSource.addEventListener("customEvent", function(event) {
                console.log("收到自定义事件:", event.data);
            });

            ✅ 定时心跳保持连接

            ScheduledExecutorService heartbeatScheduler = Executors.newScheduledThreadPool(1);
            heartbeatScheduler.scheduleAtFixedRate(() -> {
                try {
                    emitter.send("heartbeat");
                } catch (IOException e) {
                   php emitter.completeWithError(e);
                }
            }, 0, 15, TimeUnit.SECONDS);

            九、总结

            特性支持情况
            异步发送
            多用户并发
            超时与关闭管理
            自定义事件类型
            应用场景实时推送、轻量通知

            到此这篇关于Spring SseEmitter 系统详细讲解的文章就介绍到这了,更多相关Spring SseEmitter 系统内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

            0

            上一篇:

            下一篇:

            精彩评论

            暂无评论...
            验证码 换一张
            取 消

            最新开发

            开发排行榜