Spring Boot 整合 SSE(Server-Sent Events)

06-01 1504阅读

1、简述

SSE(Server-Sent Events)是一种基于HTTP协议的单向通信机制,允许服务器向浏览器持续发送实时更新。与WebSocket不同,SSE更简单,使用HTTP/1.1协议即可,不需要额外的协议升级。

SSE的特点:

  • 单向通信:服务器推送数据给客户端,客户端无法向服务器发送消息。

  • 简单易用:基于HTTP协议,无需复杂的配置。

  • 浏览器支持:现代浏览器大多内置支持(如Chrome、Edge、Firefox等)。

    2、Spring Boot 中的SSE实现

    2.1 添加依赖

    SSE无需额外的依赖,Spring Boot自带对SSE的支持。创建一个Spring Boot项目即可。

        org.springframework.boot
        spring-boot-starter-web
    
    

    2.2 实现后端接口

    使用MediaType.TEXT_EVENT_STREAM_VALUE作为返回类型即可开启SSE。以下代码是一个简单的实现。

    package com.example.sse.controller;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.time.LocalTime;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Stream;
    @RestController
    public class SseController {
        @GetMapping(value = "/sse/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
        public Stream stream() {
            // 模拟数据流
            return Stream.generate(() -> "当前时间:" + LocalTime.now())
                         .limit(10); // 限制10条消息
        }
    }
    

    2.3 配置超时时间(可选)

    默认情况下,Spring Boot的响应会超时。可以在application.properties中调整超时时间:

    server.servlet.session.timeout=30s
    spring.mvc.async.request-timeout=30000
    

    2.4 前端实现

    SSE在前端通过EventSource对象实现。以下是一个简单的前端示例:

    
    
        
        SSE Example
    
    
        

    实时消息

    const eventSource = new EventSource('/sse/stream'); eventSource.onmessage = function(event) { const messagesDiv = document.getElementById('messages'); const newMessage = document.createElement('p'); newMessage.textContent = event.data; messagesDiv.appendChild(newMessage); }; eventSource.onerror = function() { console.error('SSE连接出错,正在尝试重连...'); eventSource.close(); };

    3、高级实践

    使用Spring Scheduler推送数据,在实际场景中,可能需要定时向客户端推送数据。例如,监控系统定时更新。

    Spring Boot 整合 SSE(Server-Sent Events)
    (图片来源网络,侵删)
    package com.example.sse.service;
    import org.springframework.http.MediaType;
    import org.springframework.stereotype.Service;
    import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
    import java.io.IOException;
    import java.util.concurrent.CopyOnWriteArrayList;
    @Service
    public class SsePushService {
        private final CopyOnWriteArrayList emitters = new CopyOnWriteArrayList();
        public SseEmitter subscribe() {
            SseEmitter emitter = new SseEmitter(30_000L);
            emitters.add(emitter);
            emitter.onCompletion(() -> emitters.remove(emitter));
            emitter.onTimeout(() -> emitters.remove(emitter));
            return emitter;
        }
        public void pushMessage(String message) {
            for (SseEmitter emitter : emitters) {
                try {
                    emitter.send(message, MediaType.TEXT_PLAIN);
                } catch (IOException e) {
                    emitters.remove(emitter);
                }
            }
        }
    }
    

    创建一个控制器订阅和推送消息:

    package com.example.sse.controller;
    import com.example.sse.service.SsePushService;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class SsePushController {
        private final SsePushService ssePushService;
        public SsePushController(SsePushService ssePushService) {
            this.ssePushService = ssePushService;
        }
        @GetMapping("/sse/subscribe")
        public SseEmitter subscribe() {
            return ssePushService.subscribe();
        }
        @GetMapping("/sse/push")
        public void pushMessage() {
            ssePushService.pushMessage("当前时间:" + System.currentTimeMillis());
        }
    }
    

    注意事项:

    Spring Boot 整合 SSE(Server-Sent Events)
    (图片来源网络,侵删)
    • 浏览器兼容性:SSE不支持IE,但现代浏览器支持良好。

    • 连接断开处理:可通过EventSource的onerror事件重新连接。

      Spring Boot 整合 SSE(Server-Sent Events)
      (图片来源网络,侵删)
    • 性能问题:对大量订阅者时,需考虑使用分布式消息队列优化(如Kafka)。

    • 超时时间:默认30秒超时,需要根据实际需求调整。

      4、适用场景

      • 实时通知:如监控系统的告警推送。

      • 实时更新:如股票行情、体育比分。

      • 消息流:如系统日志、任务进度。

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码