SpringBoot实现网页消息推送的5种方法对比

 更新时间:2026年02月11日 09:20:05   作者:AI老李  
网页消息推送是现代 Web 应用的核心功能之一,Spring Boot 提供了非常成熟的支持,本文为大家整理了 5 种主流实现方式,有需要的小伙伴可以了解下

网页消息推送(实时通知、聊天、状态更新、订单提醒等)是现代 Web 应用的核心功能之一。Spring Boot 提供了非常成熟的支持,下面整理出目前最常用、最实用的 5 种实现方式,从简单到高级排序,并标注适用场景、优缺点和核心代码要点。

1. 短轮询(Short Polling) + Ajax / Fetch

原理:前端定时(每 3–10 秒)通过 Ajax / Fetch 向后端拉取新消息。

适用场景:对实时性要求不高、开发周期短、兼容性极强

优点:实现最简单,无需额外依赖,兼容所有浏览器

缺点:服务器压力大(大量无效请求)、延迟高、不够“实时”

核心代码(后端)

@RestController
public class NotificationController {

    @GetMapping("/notifications")
    public ResponseEntity<List<String>> getNotifications() {
        // 查询是否有新消息(数据库 / Redis / 内存队列)
        List<String> newMsgs = notificationService.pollNewMessages();
        return ResponseEntity.ok(newMsgs);
    }
}

前端(Vue/React 通用):

setInterval(async () => {
  const res = await fetch('/notifications');
  const data = await res.json();
  if (data.length > 0) addNotifications(data);
}, 5000);

2. 长轮询(Long Polling)

原理:客户端发起请求,后端如果没有新消息就挂起请求(不返回),有新消息立即返回;前端收到后立即再发起下一次请求。

适用场景:实时性要求较高,但不想引入 WebSocket/SSE

优点:比短轮询节省资源,实现相对简单

缺点:连接频繁建立/断开,服务器需维护大量长连接

后端实现(使用 DeferredResult):

@GetMapping("/long-poll")
public DeferredResult<List<String>> longPoll() {
    DeferredResult<List<String>> result = new DeferredResult<>(30000L); // 30秒超时

    // 异步监听新消息(可使用消息队列或 BlockingQueue)
    messageQueue.addListener(msg -> {
        if (!result.isSetOrExpired()) {
            result.setResult(Collections.singletonList(msg));
        }
    });

    result.onTimeout(() -> result.setResult(Collections.emptyList()));
    return result;
}

3. Server-Sent Events(SSE)

原理:基于 HTTP 的单向服务器推送,客户端使用 EventSource 建立持久连接,服务端通过 text/event-stream 推送事件。

适用场景:服务器 → 客户端单向推送(如通知、进度、股票价格、日志监控)

优点:实现简单、自动重连、基于标准 HTTP、资源消耗比 WebSocket 低

缺点:单向(客户端不能主动发消息)、不支持二进制

后端核心代码(Spring Boot 推荐方式):

@GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> sseNotifications() {
    return Flux.interval(Duration.ofSeconds(1))
               .map(seq -> ServerSentEvent.<String>builder()
                   .id(String.valueOf(seq))
                   .event("message")
                   .data("服务器推送:" + LocalDateTime.now())
                   .build());
}

或使用 SseEmitter(更灵活,支持断开重连)

@GetMapping("/notifications")
public SseEmitter stream() {
    SseEmitter emitter = new SseEmitter(Long.MAX_VALUE);
    // 在其他地方调用 emitter.send() 推送
    return emitter;
}

前端

const source = new EventSource('/sse');
source.onmessage = e => console.log('收到:', e.data);

4. WebSocket(原生 / @ServerEndpoint)

原理:全双工通信通道,浏览器和服务器建立持久 TCP 连接。

适用场景:需要双向实时通信(聊天、协作编辑、游戏)

优点:真正的实时双向、低延迟

缺点:实现稍复杂、需处理断线重连、心跳

Spring Boot 简单实现

@ServerEndpoint("/ws/{userId}")
@Component
public class WebSocketEndpoint {

    private static final Map<String, Session> sessions = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        sessions.put(userId, session);
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        // 广播或点对点
    }

    public static void sendToUser(String userId, String msg) {
        Session session = sessions.get(userId);
        if (session != null && session.isOpen()) {
            session.getAsyncRemote().sendText(msg);
        }
    }
}

配置

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new MyWebSocketHandler(), "/my-ws").setAllowedOrigins("*");
    }
}

5. WebSocket + STOMP(最推荐的生产方式)

原理:在 WebSocket 上层使用 STOMP 协议(类似 HTTP 的消息协议),支持订阅主题、点对点、广播等。

适用场景:几乎所有中大型实时应用(聊天、通知、实时仪表盘、订单状态)

优点:功能强大(订阅/取消订阅、断线重连、消息确认)、易于管理用户会话、支持广播/点对点

依赖

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

配置

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue"); // 订阅前缀
        config.setApplicationDestinationPrefixes("/app"); // 发送前缀
        config.setUserDestinationPrefix("/user"); // 点对点前缀
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
                .setAllowedOriginPatterns("*")
                .withSockJS(); // 支持降级
    }
}

发送消息(广播):

@Autowired
private SimpMessagingTemplate messagingTemplate;

public void sendNotification(String message) {
    messagingTemplate.convertAndSend("/topic/notifications", message);
}

点对点(需结合 Spring Security 或自定义 Principal):

messagingTemplate.convertAndSendToUser(username, "/queue/notifications", message);

前端(使用 stomp.js 或 @stomp/stompjs):

const client = new Client({
  brokerURL: 'ws://localhost:8080/ws',
  onConnect: () => {
    client.subscribe('/topic/notifications', msg => console.log(msg.body));
    client.subscribe('/user/queue/notifications', msg => console.log(msg.body));
  }
});
client.activate();

总结对比表

方式实时性方向性复杂度资源消耗推荐场景
短轮询★☆☆☆☆双向最低原型、兼容性要求极高
长轮询★★☆☆☆双向中等实时性
SSE★★★★☆服务器→客户端服务器单向推送首选
原生 WebSocket★★★★★双向简单双向场景
WebSocket + STOMP★★★★★双向中高生产级实时应用首选

2026 年推荐优先级:

  • 大多数场景 → WebSocket + STOMP
  • 纯服务器推送、资源敏感 → SSE
  • 简单/原型 → 轮询

到此这篇关于SpringBoot实现网页消息推送的5种方法对比的文章就介绍到这了,更多相关SpringBoot网页消息推送内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java方法重载实现原理及代码实例

    Java方法重载实现原理及代码实例

    这篇文章主要介绍了Java方法重载实现原理及代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09
  • SpringBoot使用Prometheus实现监控

    SpringBoot使用Prometheus实现监控

    在当今的软件开发世界中,监控是至关重要的一部分,本文主要介绍了如何在Spring Boot应用程序中使用Prometheus进行监控,以帮助大家更好地理解和管理您的应用程序,有需要的可以参考下
    2023-10-10
  • java实现快速排序图文详解

    java实现快速排序图文详解

    网上关于快速排序的算法原理和算法实现都比较多,不过java是实现并不多,而且部分实现很难理解,和思路有点不搭调。所以整理了这篇文章。如果有不妥之处还请建议
    2021-08-08
  • spring整合redis实现数据缓存的实例代码

    spring整合redis实现数据缓存的实例代码

    这篇文章主要介绍了spring整合redis实现数据缓存,需要的朋友可以参考下
    2018-09-09
  • Spring里的Async注解实现异步操作的方法步骤

    Spring里的Async注解实现异步操作的方法步骤

    这篇文章主要介绍了Spring里的Async注解实现异步操作的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • java连接Access数据库的方法

    java连接Access数据库的方法

    这篇文章主要为大家详细介绍了java连接Access数据库的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • 如何在mapper文件中使用in("str1","str2")

    如何在mapper文件中使用in("str1","str2")

    这篇文章主要介绍了如何在mapper文件中使用in("str1","str2"),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • JAVA求两直线交点和三角形内外心的方法

    JAVA求两直线交点和三角形内外心的方法

    本文提供了JAVA求两直线交点、三角形外心、三角形内心的代码和算法讲解,大家可以参考使用
    2013-11-11
  • Java操作Word文档的全面指南

    Java操作Word文档的全面指南

    在Java开发中,操作Word文档是常见的业务需求,广泛应用于合同生成、报表输出、通知发布、法律文书生成、病历模板填写等场景,本文将全面介绍Java操作Word文档的主流方案,需要的朋友可以参考下
    2025-11-11
  • Java日常练习题,每天进步一点点(43)

    Java日常练习题,每天进步一点点(43)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07

最新评论