使用Springboot 2.7+Websocket+js实现服务端消息实时推送
创始人
2024-05-20 23:44:17
0

文章目录

  • 诉求
  • 相关技术
  • 相关步骤
    • 项目创建
    • 编写相关配置
    • 消息逻辑处理
    • 使用JavaScript实现Websocket的前端功能
    • 功能测试

诉求

       模拟服务端主动推送消息给客户端,同时展示客户端发送给客户端的消息以及服务端推送给客户的消息。

相关技术

       Springboot(2.7.0)+Websocket+javascript

相关步骤

项目创建

       创建一个Spring Boot项目,并在pom.xml文件中添加Websocket依赖。完整依赖如下


4.0.0org.springframework.bootspring-boot-starter-parent2.7.0com.exampledemo0.0.1-SNAPSHOTwardemoDemo project for Spring Boot8UTF-81.7.30org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-websocketorg.springframework.bootspring-boot-starter-tomcatprovidedorg.slf4jslf4j-api${slf4j.version}org.slf4jslf4j-log4j12${slf4j.version}org.apache.logging.log4jlog4j-to-slf4j2.14.0org.apache.maven.pluginsmaven-compiler-plugin3.1${java.version}${java.version}${java.encoding}org.apache.maven.pluginsmaven-surefire-plugin2.6org.apache.maven.pluginsmaven-release-plugin-Preleaseorg.apache.maven.pluginsmaven-source-plugin2.1truecompilejar

编写相关配置

       编写WebSocketConfig和WebSocketHandler配置类,实现对WebSocket的配置。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.*;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** @author * @date 2023年01月30日 14:07*/
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {//    @Override
//    public void configureMessageBroker(MessageBrokerRegistry registry) {
//        registry.enableSimpleBroker("/topic");
//        registry.setApplicationDestinationPrefixes("/app");
//    }@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/websocket").withSockJS();}@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** handler * @date 2023年01月30日 14:08*/
@Component
public class WebSocketHandler extends TextWebSocketHandler {private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketHandler.class);private static final List sessions = new ArrayList<>();@Overridepublic void handleTextMessage(WebSocketSession session, TextMessage message) {LOGGER.info("Received message: {}", message.getPayload());for (WebSocketSession webSocketSession : sessions) {try {webSocketSession.sendMessage(message);} catch (IOException e) {LOGGER.error("Error: {}", e.getMessage());}}}@Overridepublic void afterConnectionEstablished(WebSocketSession session) {sessions.add(session);}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) {sessions.remove(session);}
}

消息逻辑处理

       编写一个WebSocketServer类,实现服务端主动推送消息的逻辑(此处服务端推送客户端消息的逻辑采用定时任务自动推送,⚠️注意:必须在启动类中加入@EnableScheduling注解,开启定时任务的支持)。


import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;/*** @author * @date 2023年01月30日 11:19*/
@ServerEndpoint("/websocket")
@Component
public class WebSocketServer {private Session session;/*     用于存储websocket连接,key为sessionId  */private static ConcurrentHashMap webSocketServerConcurrentHashMap = new ConcurrentHashMap();@OnOpenpublic void onOpen(Session session) {this.session = session;webSocketServerConcurrentHashMap.put(session.getId(), this);System.out.println("WebSocket opened: " + session.getId());}@OnMessagepublic void onMessage(String message, Session session) {System.out.println("WebSocket message received: " + message);String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis());try {//发送的消息也返回给当前连接,用于展示session.getBasicRemote().sendText(dateStr + "发送消息:" + message);//写入DB或者其他存储系统中。。。} catch (IOException e) {e.printStackTrace();}}@OnClosepublic void onClose(Session session, CloseReason closeReason) {webSocketServerConcurrentHashMap.remove(session.getId());System.out.println("WebSocket closed: " + closeReason);}@OnErrorpublic void onError(Session session, Throwable throwable) {System.out.println("WebSocket error: " + throwable);}/*** 模拟服务端消息推送,5s推送一次(服务端 -> 客户端)*/@Scheduled(fixedRate = 5000)public void sendMessageToClient() {//没有连接时不做任何事情if (CollectionUtils.isEmpty(webSocketServerConcurrentHashMap)){return;}System.out.println("服务端发送消息到客户端");String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis());long number = new Random().nextInt(10000);webSocketServerConcurrentHashMap.forEach((k, v) -> {try {v.session.getBasicRemote().sendText(dateStr + "收到消息:" + number);//写入DB或者其他存储系统中。。。} catch (IOException e) {e.printStackTrace();}});}}

启动类中加入@EnableScheduling注解以支持定时任务

在这里插入图片描述

使用JavaScript实现Websocket的前端功能

       在页面中使用JavaScript实现Websocket的前端实现,建立连接,接收并显示消息。在页面关闭时通过JavaScript关闭Websocket连接,以确保连接正常关闭。



WebSocket Example







    功能测试

    前端效果

    在这里插入图片描述

    后端日志消息

    在这里插入图片描述

    相关内容

    热门资讯

    监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
    Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
    protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
    在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
    【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
    Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
    educoder数据结构与算法...                                                   ...
    MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
    修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
    MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...