SpringBoot 如何实现消息自动推送机制?

createh52周前 (12-12)技术教程18

在实际开发过程中,实现消息自动推送机制的方式有很多种,比较常见的方式有如下几种,WebSocket、SSE(Server-Sent Events)、消息队列(如 RabbitMQ、Kafka)等,下面我们就来看看这些方式都是如何实现消息的自动推送的。

WebSocket 实现消息推送

WebSocket是一种全双工通信协议,允许服务器和客户端之间建立持久连接,实现实时消息的双向推送。具体实现步骤如下所示。

引入依赖

在pom.xml中引入WebSocket的依赖配置,如下所示。

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

接下来就是需要创建WebSocket的配置类,用来注册WebSocket服务端断点。如下所示。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

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

创建WebSocket处理器

创建一个处理WebSocket消息的Handler类,用来对客户端的信息进行处理,如下所示。

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class MyWebSocketHandler extends TextWebSocketHandler {
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理客户端发送的消息
        String payload = message.getPayload();
        System.out.println("Received: " + payload);

        // 发送消息给客户端
        session.sendMessage(new TextMessage("Server Response: " + payload));
    }
}

前端代码

在前端实现中,我们可以通过JavaScript连接WebSocket服务端,如下所示。

var socket = new WebSocket("ws://localhost:8080/websocket-endpoint");
socket.onmessage = function(event) {
    console.log("Received from server: " + event.data);
};
socket.send("Hello, Server!");

这样就实现了服务端可以主动推送消息到客户端,客户端也可以主动向服务端发送消息。

SSE(Server-Sent Events) 实现单向推送

SSE是一种轻量级的服务端到客户端单向推送技术。与WebSocket不同,SSE是单向的,也就是说只能发送从服务器到客户端的消息。下面我们就来看看具体的实现步骤。

控制器实现

通过SpringBoot提供的SseEmitter类来实现SSE消息的推送。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RestController
public class SseController {

    private final ExecutorService executor = Executors.newSingleThreadExecutor();

    @GetMapping("/sse")
    public SseEmitter handleSse() {
        SseEmitter emitter = new SseEmitter();

        executor.execute(() -> {
            try {
                // 推送消息给客户端
                emitter.send("Server: Hello SSE Client!");
                emitter.complete();
            } catch (IOException e) {
                emitter.completeWithError(e);
            }
        });

        return emitter;
    }
}

前端实现

在服务前端通过JavaScript我们就可以连接到SSE服务,如下所示。

var eventSource = new EventSource("/sse");
eventSource.onmessage = function(event) {
    console.log("Received: " + event.data);
};

整个的SSE服务实现相对比较简单,适合从服务端推送消息到客户端的场景实现。

使用消息队列(RabbitMQ/Kafka)实现消息推送

对于需要异步处理或消息传递的应用场景,我们还可以通过消息队列来实现消息的推送,例如常见的消息队列RabbitMQ、Kafka等。下面我们展示如何通过RabbitMQ来实现相关操作。

使用RabbitMQ实现推送

首先,需要引入相关的依赖配置,如下所示。

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

添加上连接RabbitMQ的相关连接配置,如下所示。

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

消息生产者代码实现

创建一个消息生产者,将消息发送到队列中,如下所示。

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RabbitProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/send")
    public String send() {
        String message = "Hello RabbitMQ!";
        rabbitTemplate.convertAndSend("myQueue", message);
        return "Message sent!";
    }
}

消费者代码实现

创建一个消息消费者,接收来自队列的消息并推送给客户端,如下所示。

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Service;

@Service
public class RabbitConsumer {

    @RabbitListener(queues = "myQueue")
    public void consumeMessage(String message) {
        System.out.println("Received message: " + message);
        // 处理消息并推送给客户端
    }
}

通过消息队列,可以在高并发和分布式系统中实现消息的异步推送。

总结

在实际使用过程中,我们可以根据应用场景,来选择不同的技术实现消息的自动推送,例如WebSocket就比较适合需要实时双向通信的场景。SSE就比较适合服务器单向推送消息的场景。而消息队列则是适合于异步消息处理,尤其在分布式系统中。根据具体的使用场景,我们可以选择合适的方案可以帮助我们有效的实现自动推送消息的功能。

相关文章

一文带你彻底搞懂Redis实现消息的订阅发布

前言Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接受消息。Redis客户端可以订阅任意数量的频道!一、实现订阅发布功能①命令:这些命令被广泛用于构...

「Java基础」Springboot+Websocket的实现后端数据实时推送

这篇文章主要就是实现这个功能,只演示一个基本的案例。使用的是websocket技术。一.什么是websocketWebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通信,...

用JAVA和Websocket实现实时通信

说到websocket你们必定不会陌生,WebSocket是HTML5一种新的协议。它实现了浏览器与服务器全双工通讯(full-duplex)。一开始的握手须要借助HTTP请求完成,当浏览器和服务器握...

手把手告诉你如何监听 MySQL binlog 实现数据变化后的实时通知

Hello 大家好,我是阿粉。不知道大家在日常的工作中有没有遇到这样的场景,很多时候业务数据有变更需要及时加载到缓存、ES 或者发送到消息队列中通知下游服务。一般遇到这种情况下,在实时性要求不高的场景...

一套完整版Java 开源的 Spring Boot 即时通讯 IM 聊天系统(附源码)

开篇电商平台最不能缺的就是即时通讯,例如通知类下发,客服聊天等。今天,就来给大家分享一个开源的即时通讯系统。如对文章不感兴趣可直接跳至文章末尾,有获取源码链接的方法。但文章内容是需要你简单的过一遍的,...

强大 WebView2 + 不用写 JavaScript 的 htmx.js 「小轻快」开发桌面程序

WebView2 是越来越香了。WebView2 不但是 Win11 自带的系统组件,Win10 也已经自动推送安装。即使是少量没有安装 WebView2 的系统 —— 使用 aardio 中的 we...