Springboot+Vue 实现websocket推送

1、后端引入依赖

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

2、引入websocket配置

WebSocketConfig.java

/**
 * @auther pxm
 * @date 2023/6/16
 * @description
 */

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * 开启WebSocket支持
 * @author drg
 */
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
WebSocketServer.java(/websocket/** 方法需要加入白名单)
package com.fch.websocket.server;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * websocket 服务端
 *
 * @author pxm
 * @return
 * @date 2023/9/12 9:25
 */
@Slf4j
@ServerEndpoint(value = "/websocket/{clientId}")
@Component
public class WebSocketServer {

    /**
     * 记录当前在线连接数
     */
    private static AtomicInteger onlineCount = new AtomicInteger(0);

    /**
     * 存放所有在线的客户端 key 为用户Id
     */
    private static Map<String, Session> clients = new ConcurrentHashMap<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("clientId") String clientId) {
        if (clients.containsKey(clientId)) {
            clients.remove(clientId);
            clients.put(clientId, session);
        } else {
            onlineCount.incrementAndGet(); // 在线数加1
            clients.put(clientId, session);
//            sendMessage("客户端"+clientId,session);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session) {
        for (String userId : clients.keySet()) {
            if (clients.get(userId).equals(session)) {
                clients.remove(session);
                onlineCount.decrementAndGet(); // 在线数减1
            }
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("服务端收到客户端[{}]的消息:{}", session.getId(), message);
//        this.sendMessage(session.getId());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }


    /**
     * 群发消息
     *
     * @param message 消息内容
     */
    public static void sendMessage(String message) {
        for (Map.Entry<String, Session> sessionEntry : clients.entrySet()) {
            Session toSession = sessionEntry.getValue();
            try {
                log.info("服务端给客户端[{}]发送消息{}", toSession.getId(), message);
                toSession.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                log.debug("数据发送失败!疑似断开连接", toSession.getId(), message);
            }
        }
    }

    /**
     * 群发消息
     *
     * @param message 消息内容
     */
    public static void sendMessage(String message, String id) {

        Session session = clients.get(id);
        if (session != null) {
            log.debug("服务端给客户端[{}]发送消息{}", session.getId(), message);
            try {
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
                log.debug("数据发送失败!疑似断开连接", session.getId(), message);
                clients.remove(id);
            }
        }
    }

    /**
     * 根据用户id获取session
     *
     * @param userId
     * @return
     */
    public Session getUserSession(String userId) {
        return clients.get(userId);
    }
}

其中clientId参数表示websocket客户端id

3、发送websocket(传入要发送的消息以及唯一标识)

 WebSocketServer.sendMessage("message");

 4、vue页面

1、初始化参数

       // ws是否启动
      wsIsRun: false,
      // 定义ws对象
      webSocket: null,
      // ws请求链接(类似于ws后台地址)
      ws: "",
      // ws定时器
      wsTimer: null,
      //websocket客户端id
      clientId: null,

2、在ws启动并初始化

async mounted() {
    this.wsIsRun = true;
    this.wsInit();
  },

在method中写相关方法

 /****************************websocker ****************************************/
    /**
     * @description: 初始化WebSocket连接
     * @author: pxm
     * @modify:
     * @return {*}
     */
    /**
     * 初始化ws
     */
    wsInit() {
        //获取token
      this.clientId = this.$store.state.user.token;
        //通过token生成唯一客户端id
      const wsuri =
        "ws://10.10.7.175:9474/websocket/" + this.clientId + "__newInfo";
      this.ws = wsuri;
      if (!this.wsIsRun) return;
      // 初始化ws
      this.webSocket = new WebSocket(this.ws);
      // 判断当前浏览器是否支持websocket
      if (typeof WebSocket == "undefined") {
      } else {
        // 创建websocket实例
        this.websock = new WebSocket(wsuri);
        // 监听websocket的message事件
        this.websock.onmessage = this.websocketonmessage;
        // 监听websocket的open事件
        this.websock.onopen = this.websocketonopen;
        // 监听websocket的error事件
        this.websock.onerror = this.websocketonerror;
        // 监听websocket的close事件
        this.websock.onclose = this.websocketclose;
      }

      // 检查ws连接状态,readyState值为0表示尚未连接,1表示建立连接,2正在关闭连接,3已经关闭或无法打开
      clearInterval(this.wsTimer);
      this.wsTimer = setInterval(() => {
        if (this.webSocket.readyState === 1) {
          clearInterval(this.wsTimer);
        } else {
          this.wsInit();
        }
      }, 3000);
    },
    /**
     * @description: 连接建立之后执行send方法发送数据
     * @author: pxm
     * @modify:
     * @return {*}
     */
    websocketonopen() {
      // 定义一个actions对象,用于存储测试信息
      let actions = { info: "成功连接!" };
      // 将actions对象转换成JSON字符串,并发送到websocket
      this.websocketsend(JSON.stringify(actions));
    },
    /**
     * @description: 连接建立失败重连
     * @author: pxm
     * @modify:
     * @return {*}
     */
    websocketonerror() {
      // 重新初始化
      this.initWebSocket();
    },
    /**
     * @description: 数据接收(接到请求后,需要后续做的事)
     * @author: pxm
     * @modify:
     * @return {*}
     */
    websocketonmessage(e) {
      if (e.data) {
        //根据自己逻辑完善监听后功能
        this.getList(1);
      }
    },
    /**
     * @description: 数据发送
     * @author: pxm
     * @modify:
     * @param {*} Data 发送数据
     * @return {*}
     */
    websocketsend(Data) {
      this.websock.send(Data);
    },
    /**
     * @description: 关闭
     * @author: pxm
     * @modify:
     * @param {*} e 信息
     * @return {*}
     */
    websocketclose(e) {},

  • 13
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring BootVue可以通过Websocket实现后端的主动推送功能。 首先,在Spring Boot中,我们需要引入WebSocket的支持。可以在pom.xml文件中添加Spring BootWebSocket依赖。然后,创建一个WebSocket配置类,并添加注解@EnableWebSocket,用于启用WebSocket。 接下来,在配置类中,我们需要注册一个WebSocket处理器,并设置处理器的路径。可以使用@WebSocketMapping注解来指定处理器的路径,同时通过实现WebSocketHandler接口来处理WebSocket的消息。 在处理器中,我们可以重写父类的方法,例如onOpen()、onMessage()、onClose()等,来处理WebSocket的事件,如连接建立、收到消息、连接关闭等。 然后,在Vue中,我们可以使用Vue.js的插件vue-native-websocket来连接WebSocket。首先,可以使用npm安装vue-native-websocket插件。然后,在main.js文件中,引入插件并进行相关配置。 在Vue组件中,可以使用this.$socket来访问WebSocket连接,并通过监听连接的事件,如open、message、close等,来处理WebSocket的事件。 在进行WebSocket连接后,后端可以在需要的时候,主动向前端发送消息。可以使用WebSocket的sendMessage()方法,将消息发送给所有连接的WebSocket客户端。 总结起来,Spring BootVue可以通过WebSocket实现后端的主动推送功能。在Spring Boot中,需要通过WebSocket配置类来注册WebSocket处理器,并在处理器中处理WebSocket的事件。在Vue中,可以使用vue-native-websocket插件来连接WebSocket,并通过监听事件来处理WebSocket的事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值