开发者

SpringBoot环境下服务端向客户端主动推送数据的几种常见方式

目录
  • 前言
  • 一、什么是“服务端推送”?
  • 二、常用推送技术概述
  • 三、方法一:长轮询(Long Polling)
    • 1. 原理简介
    • 2. 优点
    • 3. 缺点
    • 4. Spring Boot 示例代码
      • Controller 层
      • 客户端模拟(JaandroidvaScript)
  • 四、方法二:Server-Sent Events(SSE)
    • 1. 原理简介
      • 2. 优点
        • 3. 缺点
          • 4. Spring Boot 示例代码
            • Controller 层
            • 客户端代码(html + JavaScript)
        • 五、方法三:WebSocket
          • 1. 原理简介
            • 2. 优点
              • 3. 缺点
                • 4. Spring Boot 示例代码
                  • 1. 添加依赖(pom.XML)
                  • 2. 配置 WebSocket
                  • 3. 发送消息的 Controller
                  • 4. 客户端代码(使用 Sockjs + Stomp.js)
              • 六、其他方式简要介绍
                • 1. MQTT(适用于物联网场景)
                  • 2. 消息队列 + 客户端监听(如 RabbitMQ)
                  • 七、对比总结表
                    • 八、如何选择合适的方法?
                      • 九、结语

                        前言

                        在传统的 HTTP 请求-响应模型中,客户端需要主动发起请求,服务端才能返回数据。然而,在某些场景下(如实时聊天、股票行情更新、通知系统等),我们希望服务端能够主动向客户端推送数据。本文将详细介绍在 Spring Boot 环境下实现服务端向客户端主动推送数据的几种常见方式,并比较它们的优缺点和适用场景。

                        一、什么是“服务端推送”?

                        “服务端推送”是指服务端在没有收到客户端请求的情况下,主动将数据发送给客户端。这种机制打破了传统 HTTP 的单向通信限制,适用于需要实时交互的场景。

                        二、常用推送技术概述

                        以下是目前主流的几种服务端向客户端推送数据的方式:

                        1. 长轮询(Long Polling)
                        2. Server-Sent Events(SSE)
                        3. WebSocket
                        4. MQTT(物联网常用)
                        5. 基于消息中间件 + 客户端监听(如 RabbitMQ + STOMP)

                        本文主要聚焦于前三种与 Spring Boot 集成较为方便的技术。

                        三、方法一:长轮询(Long Polling)

                        1. 原理简介

                        客户端定时或持续发起请求到服务端,服务端如果无新数据则保持连接不返回,直到有数据或超时后才响应。客户端收到响应后立即发起下一次请求。

                        2. 优点

                        • 兼容性好,支持所有浏览器
                        • 实现简单,适合小型项目或低频更新编程

                        3. 缺点

                        • 连接频繁建立销毁,资源消耗大
                        • 推送延迟较高

                        4. Spring Boot 示例代码

                        Controller 层

                        @RestController
                        public class LongPollingController {
                        
                            private String latestData = "No new data";
                        
                            @GetMapping("/poll")
                            public String poll(@RequestParam String clientId) throws InterruptedException {
                                synchronized (this) {
                                    wait(10000); // 模拟等待新数据
                                }
                                return latestData;
                            }
                        
                            @PostMapping("/update")
                            public void updateData(@RequestBody Map<String, String> payload) {
                                this.latestData = payload.get("data");
                                synchronized (this) {
                                    notifyAll(); // 通知所有等待线程
                                }
                            }
                        }
                        

                        客户端模拟(javascript)

                        function startPolling() {
                          fetch("/poll?clientId=1")
                            .then((res) => res.text())
                            .then((data) => {
                              console.log("Received:", data)
                              startPolling() // 继续下一次轮询
                            })
                        }
                        
                        startPolling()
                        

                        四、方法二:Server-Sent Events(SSE)

                        1. 原理简介

                        SSE 是 html5 提供的一种服务器向客户端推送事件的标准协议。它是单向通信,即服务端可以不断向客户端发送数据,但客户端不能通过该通道向服务端发送数据。

                        2. 优点

                        • 实时性强
                        • 协议轻量,易于实现
                        • 支持自动重连

                        3. 缺点

                        • 只能服务端推送送,不支持双向通信
                        • 不兼容 IE 浏览器

                        4. Spring Boot 示例代码

                        Controller 层

                        @RestController
                        public class SseController {
                        
                            private final List<SseEmitter> emitters = new CopyOnWriteArrayList<>();
                        
                            @GetMapping("/subscribe")
                            public SseEmitter subscribe() {
                                SseEmitter emitter = new SseEmitter(60_000L); // 超时时间
                                emitters.add(emitter);
                                emitter.onCompletion(() -> emitters.remove(emitter));
                                return emitter;
                            }
                        
                            @PostMapping("/send")
                            public void sendData(@RequestBody Map<String, String> payload) {
                                String message = payload.get("message");
                                emitters.forEach(emitter -> {
                                    try {
                                        emitter.send(message);
                                    } catch (IOException e) {
                                        emitter.complete();
                                        emitters.remove(emitter);
                                    }
                                });
                            }
                        }
                        

                        客户端代码(HTML + JavaScript)

                        <script>
                          const eventSource = new EventSource("/subscribe")
                        
                          eventSource.onmessage = function (event) {
                            console.log("New message:", event.data)
                          }
                        
                          eventSource.onerror = function (err) {
                            console.error("EventSource failed:", err)
                          }
                        </script>
                        

                        五、方法三:WebSocket

                        1. 原理简介

                        WebSocket 是一种全双工通信协议,允许服务端和客户端之间建立持久连接并随时互相发送数据。是目前最强大的实时通信解决方案之一。

                        2. 优点

                        • 实时性强,延迟低
                        • 支持双向通信
                        • 数据传输效率高

                        3. 缺点

                        • 实现相对复杂
                        • 需要客户端和服务端都支持 WebSocket
                        • 部分防火墙或代理可能不支持

                        4. Spring Boot 示例代码

                        1. 添加依赖(pom.xml)

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

                        2. 配置 WebSocket

                        @Configuration
                        @EnableWebSocketMessageBroker
                        public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
                        
                            @Override
                            public void registerStompEndpoints(StompEndpointRegistry registry) {
                                registry.addEndpoint("/ws").withSockJS();
                            }
                        
                            @Override
                            public void configureMessageBroker(MessageBrokerRegistry registry) {
                                registry.enableSimpleBroker("/topic");
                                registry.setApplicationDestinationPrefixes("/app");
                            }
                        }
                        

                        3. 发送消息的 Controller

                        @Controller
                        public class WsController {
                        
                            @Autowired
                            private SimpMessagingTemplate messagingTemplate;
                        
                            @PostMapping("/broadcast")
                            public void broadcast(@RequestBody Map<String, String> payload) {
                                String message = payload.get("message");
                                messagingTemplate.convertAndSend("/topic/messages", message);
                            }
                        }
                        

                        4. 客户端代码(使用 SockJS + Stomp.js)

                        <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
                        <script src=编程客栈"https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script>
                        
                        <script>
                          const socket = new SockJS("/ws")
                          const stompClient = Stomp.over(socket)
                        
                          stompClient.connect({}, () => {
                            stompClient.subscribe("/topic/messages", (msg) => {
                              console.log("Received:", msg.body)
                            })
                          })
                        </script>
                        

                        六、其他方式简要介绍

                        1. MQTT(适用于物联网场景)

                        • 轻量级发布/订阅协议
                        • 适用于设备间通信
                        • 可以结合 Spring Boot + EMQX / Mosquitto 使用

                        2. 消息队列 + 客户端监听(如 RabbitMQ)

                        • 服务端将数据发到 MQ
                        • 客户端监听某个队列或 Exchange
                        • 适合解耦和分布式系统架构

                        七、对比总结表

                        方法通信方向是否实时是否双向易用性适用场景
                        长轮询单向否(延迟高)简单简单场景、兼容性要求高
                        SSE单向较简单实时数据展示(如新闻、监控)
                        WebSocket双向非常实时较复杂聊天、协同编辑、游戏等
                        MQTT双向非常实时较复杂物联网、低带宽环境
                        消息队列 + 监听双向非常实时较复杂分布式系统、微服务

                        八、如何选择合适的python方法?

                        根据以下因素进行权衡:

                        • 是否需要双向通信?
                        • 对实时性的要求有多高?
                        • 客户端是否支持新技术(如 WebSocket)?
                        • 是否有资源限制(如移动端、IoT 设备)?
                        • 是否已有消息中间件?

                        九、结语

                        随着 Web 技术的发展,服务端主动推送数据已经不再是难题。Spring Boot 提供了丰富的组件来支持各种推送方式。开发者应根据业务需求、性能考量以及技术栈特点,选择最适合的推送方php案。

                        如果你正在开发一个实时性要求高的应用,推荐优先考虑 WebSocket;如果是简单的数据流推送,可以尝试 SSE;而如果必须支持老旧浏览器或低频更新,长轮询仍然是一个可行的选择。

                        以上就是SpringBoot环境下服务端向客户端主动推送数据的几种常见方式的详细内容,更多关于SpringBoot服务端向客户端推送数据的资料请关注编程客栈(www.devze.com)其它相关文章!

                        0

                        上一篇:

                        下一篇:

                        精彩评论

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

                        最新开发

                        开发排行榜