若依二次开发WebSocket实战

1. 添加WebSocket依赖

在ruoyi-framework/pom.xml中添加Spring Boot WebSocket的依赖:

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

2.在ruoyi-framework中创建一个WebSocketConfig配置类,如下所示:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** 开启WebSocket支持*/
@Configuration
public class WebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

3、在ruoyi-framework中创建一个WebSocketServer控制器类,用于处理WebSocket连接和消息

这个类主要用于使用创建连接、监听消息和发送消息等

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;// @ServerEndpoint 声明并创建了webSocket端点, 并且指明了请求路径
// id 为客户端请求时携带的参数, 用于服务端区分客户端使用
@ServerEndpoint("/ws/{sid}")
@Component
public class WebSocketServer {// 日志对象private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);// 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。private static int onlineCount = 0;// concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();// private static ConcurrentHashMap<String,WebSocketServer> websocketList = new ConcurrentHashMap<>();// 与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;// 接收sidprivate String sid = "";/** 客户端创建连接时触发* */@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {this.session = session;webSocketSet.add(this); // 加入set中addOnlineCount(); // 在线数加1log.info("有新窗口开始监听:" + sid + ", 当前在线人数为" + getOnlineCount());this.sid = sid;try {sendMessage("连接成功");} catch (IOException e) {log.error("websocket IO异常");}}/*** 客户端连接关闭时触发**/@OnClosepublic void onClose() {webSocketSet.remove(this); // 从set中删除subOnlineCount(); // 在线数减1log.info("有一连接关闭!当前在线人数为" + getOnlineCount());}/*** 接收到客户端消息时触发*/@OnMessagepublic void onMessage(String message, Session session) {log.info("收到来自窗口" + sid + "的信息:" + message);// 群发消息for (WebSocketServer item : webSocketSet) {try {item.sendMessage(message);} catch (IOException e) {e.printStackTrace();}}}/*** 连接发生异常时候触发*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("发生错误");error.printStackTrace();}/*** 实现服务器主动推送(向浏览器发消息)*/public void sendMessage(String message) throws IOException {log.info("服务器消息推送:"+message);this.session.getBasicRemote().sendText(message);}/*** 发送消息到所有客户端* 指定sid则向指定客户端发消息* 不指定sid则向所有客户端发送消息* */public static void sendInfo(String message, @PathParam("sid") String sid) throws IOException {log.info("推送消息到窗口" + sid + ",推送内容:" + message);for (WebSocketServer item : webSocketSet) {try {// 这里可以设定只推送给这个sid的,为null则全部推送if (sid == null) {item.sendMessage(message);} else if (item.sid.equals(sid)) {item.sendMessage(message);}} catch (IOException e) {continue;}}}public static synchronized int getOnlineCount() {return onlineCount;}public static synchronized void addOnlineCount() {WebSocketServer.onlineCount++;}public static synchronized void subOnlineCount() {WebSocketServer.onlineCount--;}public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {return webSocketSet;}}

4、前端页面的配置

<template><!-- 包含音频播放功能的包装元素 --><div id="wrap" v-show="false"> <!-- v-show="false" 隐藏此元素 --><!-- 音频播放控件 --><audio v-if="false" src="@/api/audio/preview.mp3" id="audio" preload="auto" muted autoplay type="audio/mp3" controls="controls"><span id="audioId">播放音乐</span></audio></div>
</template><script>
export default {// 【1】组件创建时初始化 WebSocket 连接created() {this.initWebSocket();},// 【2】组件销毁时关闭 WebSocket 连接destroyed() {this.websock.close(); //离开路由之后断开websocket连接},// 【3】方法methods: {// 3.1初始化 WebSocket连接initWebSocket() {const wsuri = "ws://localhost:8080/ws/123214";  // WebSocket 服务器的 URIif (typeof WebSocket === "undefined") {     // 检查浏览器是否支持 WebSocketconsole.log("您的浏览器不支持WebSocket");} else {console.log(wsuri);// 创建 WebSocket 连接this.websock = new WebSocket(wsuri); // 设置 WebSocket 各种事件处理函数this.websock.onmessage = this.websocketonmessage; // 接收到消息时调用this.websock.onopen = this.websocketonopen; // 连接成功时调用this.websock.onerror = this.websocketonerror; // 连接错误时调用this.websock.onclose = this.websocketclose; // 连接关闭时调用}},// 3.2连接建立之后执行send方法发送数据websocketonopen() {let actions = { "test": "我已在线" };   // 创建一个消息对象this.websocketsend(JSON.stringify(actions));   // 发送 JSON 格式的消息},// 3.3连接建立失败重连websocketonerror() {this.initWebSocket();   // 重新初始化 WebSocket 连接},// 3.4数据接收websocketonmessage(e) {this.$modal.msg(e.data);   // 显示接收到的消息console.log(e.data);   // 打印接收到的消息var audio = document.querySelector("audio");   // 获取音频元素 用这种标签名称获取的方式就不会报错了audio.currentTime = 0;   // 从头开始播放audio.muted = false;   // 取消静音audio.play();   // 音频播放// const redata = JSON.parse(e.data);   // 可用于解析 JSON 格式的消息(如果需要)},// 3.5向服务器发送数据websocketsend(Data) {this.websock.send(Data);   // 使用 WebSocket 连接发送数据},// 3.6WebSocket 连接关闭时调用websocketclose(e) {console.log('断开连接', e);   // 打印连接断开的信息}}
}
</script>

audio是因为业务场景需要引入的,主要是对与来订单提醒的提示音,然后可以在websocketonmessage()接受数据和进行处理

5、SecurityConfig设置匿名访问

这个主要是方便我们测试
请添加图片描述

整体结构(仅供参考)
请添加图片描述

6.运行效果

前端

在这里插入图片描述

后端

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/399721.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代理用上了,docker都不能用的解决方案

https://docs.docker.com/engine/daemon/proxy/https://docs.docker.com/engine/daemon/proxy/ 1、 sudo mkdir -p /etc/systemd/system/docker.service.d 2、/etc/systemd/system/docker.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=http://127.0.…

【Python实现代码视频/视频转字符画/代码风格视频】

该程序改良自GitHub开源项目VideoCharDraw 在源程序CharDraw_thread.py 带压缩和多线程版本字符画的基础上使用Tkinter库添加了图形化的操作&#xff0c;使用户操作体验更方便。 什么是视频字符画&#xff1f; 视频转字符画是一种将视频中的每一帧图像转换为由字符组成的图…

20240813作业

#include<head.h> #define SER_PORT 8888 //与服务器保持一致 #define SER_IP "192.168.106.1" //服务器ip地址 #define CLI_PORT 6666 //客户端端口号 #define CLI_IP "192.168.106.128" //客户端ip地址 int …

CI/CD——CI持续集成实验

目录 一. 安装Docker 二. 部署Jenkins 三. 配置邮箱 四. Harbor部署 五. Nexus Repository部署 五. sonarqube安装 六. 配置Docker 七. jenkins系统配置sonarqube 八. 配置pipeline 九. 构建并集成 一. 安装Docker docker-ce镜像_docker-ce下载地址_docker-ce安装教程…

Java入门基础16:集合框架1(Collection集合体系、List、Set)

集合体系结构 Collection是单列集合的祖宗&#xff0c;它规定的方法&#xff08;功能&#xff09;是全部单列集合都会继承的。 collection集合体系 Collection的常用方法 package com.itchinajie.d1_collection;import java.util.ArrayList; import java.util.HashSet;/* * 目…

靶机:DC-4

一、信息收集 1、主机发现 nmap 192.168.236.0/24 2、端口扫描 nmap 192.168.236.175 -p- -A 3、目录扫描 dirb http://192.168.236.175 二、漏洞探测 访问80端口&#xff0c;发现登录页面 尝试爆破密码 hydra -l admin -P /usr/share/wordlists/rockyou.txt 192.168.236…

修改docker的/var/lib/docker/overlay2储存路径

目录 目录 1.准备新的存储位置 1.创建新的存储目录 2.修改目录权限 2. 配置 Docker 使用新的存储位置 1.停止 Docker 服务 2.编辑 Docker 配置文件 3.迁移现有 Docker 数据 1.将现有的 Docker 数据从系统盘移动到新目录 2.启动 Docker 服务 3. 验证更改 4. 清理旧的…

Vue 3+Vite+Eectron从入门到实战系列之(五)一后台管理登录页

前面已经讲了不少基础知识&#xff0c;这篇开始&#xff0c;我们进行实操&#xff0c;做个后台管理系统&#xff0c;打包成多端的,可安装的桌面app!!其中&#xff0c;登录&#xff0c;退出的提示信息用系统的提示&#xff0c;不使用elemengplus的弹窗提示&#xff01;&#xff…

基于料面视频图像分析的高炉异常状态智能感知与识别

源自&#xff1a;自动化学报 作者&#xff1a;朱霁霖 桂卫华 蒋朝辉 陈致蓬 方怡静 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 人工智能、大数据、多模态大模型、计算机视觉、自然语言处理、数字孪生、深度强化学习 …

shuishusihui

互斥量 使用互斥量可以用于保护某些临界资源&#xff0c;同一时间只能有一个任务来使用它。 使用互斥量会引入其他问题&#xff0c;比如说优先级反转&#xff0c;于是提出了优先级继承等方法解决问题 任务通知 任务通知就是通知任务&#xff0c;前边都是多对多的关系&#xff0…

从零开始构建基于ChatGPT的嵌入式(Embedding)本地医疗客服问答机器人模型(看完就会,看到最后有惊喜)

1、前言 代码全部开源,GitHub地址为: github.com/aehyok/go-o… 前端完全也能搭建&#xff0c; 前端完全也能搭建&#xff0c; 前端完全也能搭建&#xff0c; 本文中我使用的是后端语言golang,来调用的所有外部接口&#xff0c;但它们均是restful api,所以如果你使用的是其他…

此处不允许使用 ‘空‘ 类型

说明&#xff1a;受最近看的书《设计模式之美》&#xff08;小争哥&#xff09;的影响&#xff0c;最近编码有意将一些业务逻辑写在对象里面&#xff0c;增强封装性。在此记录一次项目启动时的报错&#xff0c;如下&#xff1a; 原因&#xff1a;当你在实体类对象中&#xff0c…

提升医疗器械维修技术必经的几个阶段

01 懵懂入门阶段 初入医疗器械维修领域&#xff0c;就如同踏入了一个充满未知的神秘世界。此时&#xff0c;菜鸟们对各种医疗器械的了解仅限于书本知识和简单的操作培训。他们可能刚刚熟悉了一些基本工具的使用方法&#xff0c;对常见的医疗器械类型和品牌有了初步的认识&#…

java设计模式-桥接模式

一. 概述 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;用于将抽象部分与其实现部分分离&#xff0c;使它们可以独立地变化。桥接模式主要目的是解决当一个类存在多个继承等级时&#xff0c;由于继承带来的耦合问题&#xff0c;以及扩展性不…

计算机网络408考研 2015

计算机网络408考研2015年真题解析_哔哩哔哩_bilibili 1 1线路编码(NRZ,NRZI,8B/10B,Manchester)与加扰_nrz编码-CSDN博客 1 1 11

19c做好这件事,大幅提升Data Pump工作效率

老司机遇到的新问题 expdp是Oracle 10g引入的数据导出工具&#xff0c;能够提供并行、压缩及元数据导出等更多的功能&#xff0c;在后续的版本中逐渐替代了传统的数据导出工具exp&#xff0c;是数据库开发运维常用的工具之一。在我的印象中&#xff0c;这个工具除了诸如大量的…

河北移动:核心系统数据库成功完成整体迁移 ,实现全栈国产|OceanBase案例

本文作者&#xff1a;移动通信集团河北有限公司架构规划专家&#xff0c;房瑞 项目背景&#xff1a; 中国移动通信集团河北有限公司一直在积极响应国家及集团的号召&#xff0c;以磐舟&磐基云原生为底座&#xff0c;结合国产浏览器、中间件、数据库、操作系统和服务器等&a…

Jupyter Notebook介绍、安装及使用教程

文章目录 一.什么是Jupyter Notebook&#xff1f;1.Jupyter Notebok简介2.组成部分3.Jupyter Notebook的主要特点 二.安装Jupyter Notebook0.先试用再决定1.安装①安装前提②使用Anaconda安装③使用pip命令安装 三.运行Jupyter Notebook0.帮助1.启动①默认端口启动②指定端口启…

零基础学会机器学习,到底要多久?

这两天啊&#xff0c;有不少朋友和我说&#xff0c;想学机器学习&#xff0c;但是之前没有基础&#xff0c;不知道能不能学得会。 首先说结论&#xff0c;只要坚持&#xff0c;就能学会&#xff0c;但是一定不能三天打鱼两天晒网&#xff0c;要持之以恒&#xff0c;至少每隔两…

自由职业四年,我整理了一些建议

我是勋荣&#xff0c;一个独立开发者。运营了自己的社群&#xff0c;有自己的软件产品。目前还在探索各种副业的路上~ 1我的独立开发之路 刚毕业就找不到Android岗位的我瑟瑟发抖。在广州&#xff0c;稀里糊涂做了Java后端开发。有一天加班 通宵&#xff0c;早上借住在同事家…