SpringBoot 消息推送之 WebSocket 和 SseEmitter

用途

  • 实时获取服务端的最新数据
  • 查看调度任务的进度和执行状态
  • 用户感知:修改数据后,相关用户收到信息
  • 提升用户体验:耗时业务异步处理(Excel导入导出,复杂计算)

前端轮询

这种方式实现简单,前端通过setInterval定时去请求接口来获取最新的数据,当实时性要求不高,更新频率低的情况下可以使用这种方式。但是当实时性很高的时候,我们的请求会很频繁,服务器的消耗非常大,而且每次请求的时候服务端的数据可能还没有改变,导致很多请求都是没有意义的。

    setInterval(function () {
   
            // 请求接口操作
            // 。。。
        },
        3000
    );

webSocket

WebSocket是基于TCP协议的,它是全双工通信的,服务端可以向客户端发送信息,客户端同样可以向服务器发送指令,常用于聊天应用中。

pom.xml

SpringBoot提供了websocket的starter

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

注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint

@Configuration
public class WebSocketConfig {
   
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
   
        return new ServerEndpointExporter();
    }
}
server类

创建一个服务类:

  • 加上@ServerEndpoint注解,设置WebSocket连接点的服务地址。
  • 创建AtomicInteger用于记录连接数
  • 创建ConcurrentHashMap用于存放连接信息
  • @OnOpen注解表明该方法在建立连接后调用
  • @OnClose注解表明该方法在断开连接后调用
  • @OnError注解表明该方法在连接异常调用
  • @OnMessage注解表明该方法在收到客户端消息后调用
  • 创建推送信息的方法
  • 创建移除连接的方法
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketServer {
   

    private final static Logger logger = LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * 当前连接数
     */
    private static AtomicInteger count = new AtomicInteger(0);

    /**
     * 使用map对象,便于根据userId来获取对应的WebSocket,或者放redis里面
     */
    private static Map<String, WebSocketServer> websocketMap = new ConcurrentHashMap<>();

    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 对应的用户ID
     */
    private String userId = "";

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
   
        try {
   
            this.session = session;
            this.userId = userId;
            websocketMap.put(userId, this);
            // 数量+1
            count.getAndIncrement();
            logger.info("websocket 新连接:{}", userId);
        } catch (Exception e) {
   
            logger.error("websocket 新建连接 IO异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
   
        // 删除
        websocketMap.remove(this.userId);
        // 数量-1
        count.getAndDecrement();
        logger.info("close websocket : {}", this.userId);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message) {
   
        logger.info("来自客户端{}的消息:{}", this.userId, message);
    }

    @OnError
    public void onError(Throwable error) {
   
        logger.info("websocket 发生错误,移除当前websocket:{},err:{}", this.userId, error.getMessage()
  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 中使用 WebSocket 进行消息推送非常简单。以下是一个简单的示例: 1. 首先,在 pom.xml 文件中添加以下依赖: ``` <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> </dependencies> ``` 2. 创建一个 WebSocket 配置类,用于配置 WebSocket 相关的操作。在该类上添加 `@Configuration` 和 `@EnableWebSocket` 注解,示例代码如下: ``` @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/myHandler") // 指定处理器和URL地址 .setAllowedOrigins("*"); // 允许跨域访问 } @Bean public WebSocketHandler myHandler() { return new MyWebSocketHandler(); } } ``` 3. 创建一个自定义的 WebSocket 处理器,用于处理 WebSocket 相关的操作逻辑。示例代码如下: ``` public class MyWebSocketHandler extends TextWebSocketHandler { private List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); // 保存所有连接的 Session @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); // 添加新的连接 Session } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { String payload = message.getPayload(); // 处理接收到的消息 // ... // 将处理结果发送给所有连接的客户端 sendMessageToAll(payload); } private void sendMessageToAll(String message) throws IOException { for (WebSocketSession session : sessions) { session.sendMessage(new TextMessage(message)); } } } ``` 4. 在 Controller 类中编写发送消息的接口,示例代码如下: ``` @RestController public class MessageController { @Autowired private WebSocketHandler myHandler; @GetMapping("/sendMessage") public String sendMessage(@RequestParam("message") String message) throws IOException { myHandler.sendMessageToAll(message); // 调用自定义的 WebSocket 处理器发送消息 return "消息已发送!"; } } ``` 5. 启动应用程序,并访问 `/sendMessage` 接口发送消息,可以收到消息WebSocket 客户端会收到推送消息。 以上就是使用 Spring Boot 进行 WebSocket 消息推送的简单示例。有关更详细的配置和使用,请参考 Spring Boot 官方文档和相应的 WebSocket 规范。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值