SpringBoot实时推送的三个经典案例

 更新时间:2026年03月25日 09:35:38   作者:liangkang  
本文主要介绍了Spring Boot实时推送三个经典案例,包括长轮询、WebSocket和GraphQL订阅,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在现代Web应用中,实时消息推送已经成为一项关键功能。它不仅能够提升用户体验,还能在诸如聊天应用、实时通知系统等领域发挥重要作用。Spring Boot作为一个流行的后端框架,提供了多种实现实时消息推送的方法。本文将详细介绍三个经典案例,分别是使用长轮询(Long Polling)、WebSocket和GraphQL实现实时消息推送。

案例一:长轮询(Long Polling)

长轮询是对传统短轮询的一种改进,通过减少无效请求来降低服务器压力。在短轮询中,客户端会定期向服务器发送请求以检查是否有新的消息。这种方式会频繁占用服务器资源,特别是在消息不频繁更新的情况下。

长轮询则通过保持一个打开的连接直到有新消息到达来改进这一点。客户端发起一个请求,服务器会延迟响应,直到有新数据或连接超时。在Spring Boot中,可以使用DeferredResult来实现长轮询。

实现步骤

创建控制器:定义一个控制器来处理长轮询请求和消息发布。

@Controller
@RequestMapping(“/polling”)
public class PollingController {
// 存放监听某个Id的长轮询集合
public static Multimap<String, DeferredResult> watchRequests = Multimaps.synchronizedMultimap(HashMultimap.create());
@GetMapping(path = "watch/{id}")
@ResponseBody
public DeferredResult<String> watch(@PathVariable String id) {
    DeferredResult<String> deferredResult = new DeferredResult<>(TIME_OUT);
    deferredResult.onCompletion(() -> watchRequests.remove(id, deferredResult));
    watchRequests.put(id, deferredResult);
    return deferredResult;
}
@GetMapping(path = "publish/{id}")
@ResponseBody
public String publish(@PathVariable String id) {
    if (watchRequests.containsKey(id)) {
        Collection<DeferredResult<String>> deferredResults = watchRequests.get(id);
        for (DeferredResult<String> deferredResult : deferredResults) {
            deferredResult.setResult("我更新了" + new Date());
        }
    }
    return "Published";
}
}

前端处理:前端需要处理长轮询请求和响应,当收到非超时响应时,更新页面数据并重新发起长轮询请求。

长轮询的优势在于相对实时且减少了服务器资源的浪费,但依然存在较多请求的问题。

案例二:WebSocket

WebSocket提供了一种在单个TCP连接上进行全双工通信的方法。它使得客户端和服务器之间的数据交换变得更加简单和高效。

实现步骤

配置WebSocket:在Spring Boot中配置WebSocket处理器。

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new WebSocketHandler(), “/ws”).setAllowedOrigins(“*”);
}
}

创建WebSocket处理器:处理WebSocket连接和消息。

public class WebSocketHandler extends TextWebSocketHandler {
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String payload = message.getPayload();
session.sendMessage(new TextMessage("Hello, " + payload + “!”));
}
}

前端处理:前端使用JavaScript创建WebSocket连接,并处理消息的接收和发送。

WebSocket的优势在于能够实时、双向通信,非常适合需要频繁更新的场景,如实时聊天应用。

案例三:GraphQL订阅

GraphQL是一种用于API的查询语言,它允许客户端精确地请求所需的数据。GraphQL的订阅功能使得它也能够用于实时数据推送。

实现步骤

集成GraphQL:在Spring Boot项目中集成GraphQL库。

pom.xml中添加GraphQL依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-graphql</artifactId>
    <version>2.7.9</version>
</dependency>

定义GraphQL Schema:包括类型定义、查询和订阅操作。

定义消息类型

type Message {
id: ID!
content: String!
}

定义订阅

type Subscription {
newMessage: Message
}

实现Resolver:处理GraphQL查询和订阅请求。

@Component
public class GraphQLSubscriptionResolver {
private Publisher messagePublisher = Flux.create(emitter -> {
// 模拟消息发布
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(() -> {
Message message = new Message();
message.setId(UUID.randomUUID().toString());
message.setContent("New message at " + new Date());
emitter.next(message);
}, 0, 5, TimeUnit.SECONDS);
});
@SubscriptionMapping
public Publisher<Message> newMessage() {
    return messagePublisher;
}}

前端处理:前端使用GraphQL客户端订阅新消息,并处理接收到的数据。

GraphQL订阅的优势在于能够精确请求所需数据,并且能够在数据变化时实时推送更新。

总结

本文介绍了三种使用Spring Boot实现实时消息推送的方法:长轮询、WebSocket和GraphQL订阅。每种方法都有其独特的优势和适用场景。长轮询适用于对实时性要求不是特别高,但需要减少服务器资源浪费的场景;WebSocket适用于需要频繁双向通信的场景;GraphQL订阅则适用于需要精确请求数据并实时更新的场景。根据具体需求选择合适的方法,可以实现高效、实时的消息推送功能。

到此这篇关于SpringBoot实时推送的三个经典案例的文章就介绍到这了,更多相关SpringBoot实时推送内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一篇超详细的Spring Boot整合Mybatis文章

    一篇超详细的Spring Boot整合Mybatis文章

    大家都知道springboot搭建一个spring框架只需要秒秒钟。下面通过实例代码给大家介绍一下springboot与mybatis的完美融合,非常不错,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2021-07-07
  • Java微服务间接口调用 feign

    Java微服务间接口调用 feign

    这篇文章主要介绍了微服务间的接口调用feign,Feign是一种声明式、模板化的HTTP客户端。在spring cloud中使用Feign,可以做到类似于普通的接口的请求调用,感兴趣的小伙伴可以参考阅读
    2023-03-03
  • springMVC使用ajaxFailUpload上传图片的方法

    springMVC使用ajaxFailUpload上传图片的方法

    这篇文章主要介绍了springMVC使用ajaxFailUpload上传图片的相关知识,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-06-06
  • 深度解析Java常量池中的Integer缓冲池和String常量池

    深度解析Java常量池中的Integer缓冲池和String常量池

    为了减少对象重复创建、提升运行时效率,Java 内部提供了两种重要的优化机制Integer 缓冲池(IntegerCache)和 String 常量池(String Pool),本文将深入剖析两大常量池的底层实现、工作流程、适用范围,并通过流程图和代码示例帮助你彻底掌握
    2026-05-05
  • Java窗体中关于默认布局管理器容易踩的坑及解决

    Java窗体中关于默认布局管理器容易踩的坑及解决

    这篇文章主要介绍了Java窗体中关于默认布局管理器容易踩的坑及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Java基础语法之对象的比较方式

    Java基础语法之对象的比较方式

    文章介绍了Java中自定义类类型的比较大小的三种方式:覆写基类的equals方法、基于Comparable接口的比较、基于Comparator接口自定义比较器的比较,每种方式都有其适用场景和局限性
    2026-02-02
  • Java中的final关键字详细介绍

    Java中的final关键字详细介绍

    这篇文章主要介绍了Java中的final关键字,有需要的朋友可以参考一下
    2014-01-01
  • spring boot 配置freemarker及如何使用freemarker渲染页面

    spring boot 配置freemarker及如何使用freemarker渲染页面

    springboot中自带的页面渲染工具为thymeleaf 还有freemarker这两种模板引擎,本文重点给大家介绍spring boot 配置freemarker及如何使用freemarker渲染页面,感兴趣的朋友一起看看吧
    2023-10-10
  • Java如何获取对象属性及对应值

    Java如何获取对象属性及对应值

    这篇文章主要介绍了Java如何获取对象属性及对应值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • MyBatisPlus PaginationInterceptor分页插件的使用详解

    MyBatisPlus PaginationInterceptor分页插件的使用详解

    这篇文章主要介绍了MyBatisPlus PaginationInterceptor分页插件的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论