Spring Boot实时推送技术详解:三个经典案例

SpringBoot 整合MQTT 消息推送 springboot整合mqtt, 消息推送 阅读详情

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

案例一:长轮询(Long Polling)

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

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

实现步骤:

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

    @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";
    }
    

    }

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

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

案例二:WebSocket

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

实现步骤:

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

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

  2. 创建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 + “!”));
    }
    }

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

    WebSocket Example Send

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

案例三:GraphQL订阅

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

实现步骤:

  1. 集成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>
  1. 定义GraphQL Schema:包括类型定义、查询和订阅操作。

    定义消息类型

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

    定义订阅

    type Subscription {
    newMessage: Message
    }

  2. 实现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;
    }
    

    }

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

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

总结

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

Springboot整合Websocket(推送消息通知) 阅读详情

相关推荐

如何在Spring Boot中实现实时通知

通过本文,我们详细介绍了在Spring Boot应用中实现实时通知的两种主要方式:WebSocket和Server-Sent Events (SSE)。我们通过具体的代码示例演示了如何在Spring Boot中配置和使用这些技术,以及如何在前端页面接收和展示实时通知。今天我们将讨论如何在Spring Boot应用中实现实时通知功能,这在现代Web应用程序和服务中是非常重要的一部分。与传统的轮询或定时拉取相比,实时通知能够实现更低的延迟和更高的实时性,为用户提供更好的交互体验。

微赚开发者技术分享博客 2539

【SpringBoot+自定义注解+Aop+长轮询】实现简单的实时消息推送

平常在网站上都可以看到右上角的消息上未读消息数量,以及有消息时右下角实时弹出的例子我公司项目刚好也有这个需求,但是由于甲方要求不能使用第三方服务,于是便有了本文的解决思路

Bummon的学习随笔 1850

STM32F103C8T6+TB6612驱动直流电机全攻略(附PWM调速代码)

本文提供了一份基于STM32F103C8T6微控制器和TB6612驱动模块的直流电机驱动完整解决方案。详细解析了硬件连接、STM32CubeMX配置、HAL库驱动代码编写,并附带了PWM调速代码实现。内容涵盖从基础原理到实战调试的全过程,旨在帮助开发者快速构建稳定、可精准调速的电机控制系统,适用于智能车、机器人等嵌入式项目。

weixin_29181861的博客 586

SpringBoot DeferredResult 长轮询实现实现方式?

大概了解到这个程度差不多了,如果想要深入了解还是需要掌握挺多内容的。用简单的话来总结下 Spring DeferredResult :如果返回值类型是 DeferredResult 则表明其是异步请求,tomcat 线程不会等到应用程序处理完或者超时,...

LoveSummer 3万+

简话 RAG 本地部署(DeepSeek + RAGFlow)

RAG = DeepSeek + OLlama + Docker + RAGFlow + Windows 11 简话 RAG 本地部署

捉虫客 de 博客 1万+

手把手教你用ESP32驱动MAX30102心率血氧传感器(含完整代码)

本文详细介绍了如何使用ESP32微控制器驱动MAX30102心率血氧传感器,构建智能健康监测系统。内容涵盖PPG原理、硬件连接、驱动配置、信号处理算法以及Web服务器数据可视化,提供完整代码实现,帮助开发者快速上手物联网健康设备开发。

weixin_29208077的博客 587
上一篇: Redis之Redis事务
下一篇: SpringBoot3 升级介绍
普通网友
博客等级 码龄4年 3126粉丝 192原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值