Ruoyi集成websocket实现实时通信

适用于ruoyi项目,前端为vue,后端为mybatis

部分资料参考若依官网文档插件集成 | RuoYi

  • 业务场景

        实现前端与后端的长时间稳定通信,解决了传统Http通信带来的请求延迟高,数据量大导致堵塞等等问题。本文模拟需求为持续监控XX数据(从后端某请求获取),并传递给前端,每隔10秒进行一次更新。

  • 代码部分

        后端

        1.引入依赖

在对应模块的pom.xml下引入websocket依赖

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


 

        2.创建启动配置WebSocketConfig.java

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.config.annotation.EnableWebSocket;

import org.springframework.web.socket.server.standard.ServerEndpointExporter;



/**

 * websocket 配置

 *

 */

@Configuration

@EnableWebSocket

public class WebSocketConfig

{

    @Bean

    public ServerEndpointExporter serverEndpointExporter()

    {

        return new ServerEndpointExporter();

    }

}

默认写法,不需要修改,@Bean代表项目启动时自动启动,使用了@EnableWebSocket注解,若未指定端口,则websocket将从服务器默认端口中发出,取决于项目的application.yml

server:
# 服务器的HTTP端口,默认为8080
port: 8888

        3.创建服务配置WebSocketServer.java

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;

import javax.websocket.*;

import javax.websocket.server.ServerEndpoint;

import java.util.Map;

import java.util.Set;

import java.util.concurrent.ConcurrentHashMap;





@ServerEndpoint(value = "/webSocket")

@Component

public class WebSocketServer {

    private static Map<String , Session> clientMap = new ConcurrentHashMap<>();



    /**

     * 客户端与服务端连接成功

     * @param session

     */

    @OnOpen

    public void onOpen(Session session){

        System.out.println("ws连接成功");

        clientMap.put(session.getId(),session);

    }



    /**

     * 客户端与服务端连接关闭

     * @param session

     */

    @OnClose

    public void onClose(Session session){

        clientMap.remove(session.getId());

    }



    /**

     * 客户端与服务端连接异常

     * @param error

     * @param session

     */

    @OnError

    public void onError(Throwable error,Session session) {

        error.printStackTrace();

    }



    /**

     * 客户端向服务端发送消息

     * @param message 传递信息

     */

    @OnMessage

    public void onMsg(String message) {

        System.out.println("收到前端消息:"+message);

        //以下为模拟发送消息

        sendMessage();

    }



    /**

     * 定时向客户端发送数据(10秒间隔)

     */

    @Scheduled(cron = "0/10 * * * * ?")

    private void sendMessage(){

        //获得Map的Key的集合

        Set<String> sessionIdSet = clientMap.keySet();

        // 此处相当于一个广播操作//迭代Key集合

        for (String sessionId : sessionIdSet) {

            //根据Key得到value

            Session session = clientMap.get(sessionId);

            //发送消息给客户端,每10s给前端推送数据

            session.getAsyncRemote().sendText("我是后端发来的数据");

        }

    }

}

此java类主要存放ws各类行为触发方法,如onOpen则为客户端连接ws成功的触发器,onClose为关闭连接等等,他们通过@OnOpen、@OnClose注解绑定。

onMsg则为客户端向服务端发送消息的触发,可以在此处写一些内容或直接调用sendMessage()向客户端回复消息。

最后比较重要的,sendMessage方法,则可以直接向客户端(前端)发送内容,客户端通过回调函数可以直接获取该内容,从而在页面中显示。此处使用了定时器,实现了每隔n秒进行一次发送行为。

        4.配置匿名访问

配置该内容,可以使websocket连接跳过安全策略,实现不登录访问

在SecurityConfig.java下配置如下内容

// 如果需要不登录也可以访问,需要在`SecurityConfig.java`中设置匿名访问

("/websocket").permitAll()

注:若在客户端连接ws时,连接失败且报code:200错误时,可能是因为此步没有配置成功

前端

1.创建webSocket.js文件

export default {

  // 初始化webSocket

  webSocketInit(webSocketURL) {

    // webSocketURL为ws地址,如ws://127.0.0.1:8080/websocket

    this.webSocket = new WebSocket(webSocketURL)

    this.webSocket.onopen = this.onOpenwellback

    this.webSocket.onmessage = this.onMessageCallback

    this.webSocket.onerror = this.onErrorCallback

    this.webSocket.onclose = this.onCloseCallback

  },



  // 自定义回调函数

  setOpenCallback(callback) { //  与服务端连接打开回调函数

    this.webSocket.onopen = callback

  },

  setMessageCallback (callback) { //  与服务端发送消息回调函数

    this.webSocket.onmessage = callback

  },

  setErrorCallback (callback) { //  与服务端连接异常回调函数

    this.webSocket.onerror = callback

  },

  setCloseCallback (callback) { //  与服务端连接关闭回调函数

    this.webSocket.onclose = callback

  },

  close () { // 关闭连接

    this.webSocket.close()

  },

  sendMessage (message) { // 发送消息函数

    this.webSocket.send(message)

  },

}

2.在业务中使用

​
import webSocket from "@/api/system/webSocket";

// 连接webSocket

    connectWs() {

      webSocket.webSocketInit("ws://localhost:8888/webSocket");

      webSocket.setOpenCallback((res) => {

        console.log("建立连接成功", res);

      });

      webSocket.setMessageCallback((res) => {

        console.log("发送消息成功", res);

      });

      webSocket.setErrorCallback((res) => {

        console.log("接收失败消息", res);

      });

      webSocket.setCloseCallback((res) => {

        console.log("连接关闭", res);

      });

      webSocket.setCloseCallback((res) => {

        console.log("连接关闭", res);

      });

    },

    // 向ws服务端发送消息

    sendMessage() {

      // 使用webSocket交互

      webSocket.sendMessage("手动发消息");

    },

    //关闭websocket连接(若后台依然有定时任务,建议使用http的方式删除后台的定时任务执行)

    closeMessage() {

      webSocket.close();

    },

​

其中的webSocket.webSocketInit("ws://localhost:8888/webSocket"),ws请求地址根据情况填写,下方的各种回调函数在对应的ws行为触发时就会被调用,在此写自己的业务即可。

  • 功能验证

1.连接

连接成功后,可以在浏览器的F12中,看到打印信息

在“网络”中可以查看到连接

2.接收信息(后端->前端)

收到服务器发来的一条数据后,会在控制台打印

或者在网络->消息中查看

3.发送信息(前端->后端)

向服务端发送消息,可以在服务器的运行终端看到打印的信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值