基于SpringBoot + Vue的项目整合WebSocket的入门教程
1、WebSocket简介
WebSocket是一种网络通信协议,可以在单个TCP连接上进行全双工通信。它于2011年被IETF定为标准RFC 6455,并由RFC7936进行补充规范。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。这使得客户端和服务器之间的数据交换变得更加简单,并允许服务端主动向客户端推送数据。
2、服务端环境搭建
服务端基于SpringBoot实现,首先引入对应的jar包,然后进行ServerEndpointExporter配置,然后再定义了一个WebSocket操作类,最后编写了一个测试的类WebSocketController(一个普通的Controller类)。
2.1、maven依赖
<!-- websocket 依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.2、配置类WebSocketConfig
ServerEndpointExporter是Spring框架中的一个类,主要用于在Spring Boot应用中启动和管理WebSocket服务器端点。
在Spring Boot内置容器(嵌入式容器)中运行时,必须由ServerEndpointExporter提供ServerEndpointExporter bean,它会在启动时自动扫描和注册应用中的WebSocket端点。
注意:在Tomcat等其他容器中运行时,容器的扫描工作会由容器自己处理,不需要手动注入ServerEndpointExporter bean,即不需要该配置!!!
@Configuration
public class WebSocketConfig {/*** 注入ServerEndpointExporter,* 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}
2.3、WebSocket操作类
WebSocket操作类定义了WebSocket中的onOpen()、onMessage()、onClose()、onError()等方法,同时提供了一个发送广播(全部订阅用户)和点对点信息的方法。
1、这里@ServerEndpoint(“/api/websocket/{userId}”)中的定义可以根据自己的需要进行修改,因为我的项目里使用了SpringSecurity了,为了避免登录鉴权,这里使用“/api/**”配置了免登陆Api。后续会继续完善需要登录鉴权的使用方式。
2、这里的WebSocket操作类,每次建立 WebSocket 连接时,就会初始化一个新的 bean。这是由于 WebSocket 是一种双向的、长时间的通信机制,它需要维护每个连接的状态,处理每个从客户端发来的消息,并根据这些消息生成响应消息发送回客户端。因此,为每个 WebSocket 连接创建一个单独的 bean 是必要的,这样可以让 Spring Boot 为每个连接提供必要的管理和生命周期控制。这种方式也可以使用单例模式实现,后续再更新相关用法。
@Component
@Slf4j
@ServerEndpoint("/api/websocket/{userId}")
public class WebSocket {//与某个客户端的连接会话,需要通过它来给客户端发送数据private Session session;//用户IDprivate String userId;//concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。//虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>();// 用来存在线连接用户信息private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>();/*** 链接成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam(value="userId")String userId) {try {this.session = session;this.userId = userId;webSockets.add(this);sessionPool.put(userId, session);log.info("WebSocket消息有新的连接,总数为:"+webSockets.size());} catch (Exception e) {log.error("WebSocket异常-链接失败(onOpen),原因:" + e.getMessage());}}/*** 链接关闭调用的方法*/@OnClosepublic void onClose() {try {webSockets.remove(this);sessionPool.remove(this.userId);log.info("WebSocket消息连接断开,总数为:"+webSockets.size());} catch (Exception e) {log.error("WebSocket异常-链接关闭失败(onClose),原因:" + e.getMessage());}}/*** 收到客户端消息后调用的方法** @param message*/@OnMessagepublic void onMessage(String message) {log.info("WebSocket消息收到客户端消息:"+message);}/** 发送错误时的处理* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {log.error("用户错误,原因:"+error.getMessage());log.error("WebSocket异常-错误信息(onError),原因:" + error.getMessage());}// 此为广播消息public void sendAllMessage(String message) {log.info("WebSocket消息-广播消息:"+message);for(WebSocket webSocket : webSockets) {try {if(webSocket.session.isOpen()) {webSocket.session.getAsyncRemote().sendText(message);}} catch (Exception e) {log.error("WebSocket异常-广播消息异常(sendAllMessage),原因:" + e.getMessage());}}}// 此为单点消息public void sendOneMessage(String userId, String message) {Session session = sessionPool.get(userId);if (session != null && session.isOpen()) {try {log.info("WebSocket消息-点对点消息:"+message);session.getAsyncRemote().sendText(message);} catch (Exception e) {log.error("WebSocket异常-点对点消息异常(sendOneMessage),原因:" + e.getMessage());}}}}
2.4、测试类WebSocketController
这个测试类,主要是为了测试发送信息后,页面可以自动更新。至此,服务端的配置就完成了。
@Controller
@RequestMapping("/api/msg")
public class WebSocketController {@Resourceprivate WebSocket webSocket;@RequestMapping("/all/{msg}") // 将消息发送到/topic/greetings路径下public void all(@PathVariable String msg) {//创建业务消息信息JSONObject obj = new JSONObject();obj.put("msg", msg);//消息内容//全体发送webSocket.sendAllMessage(obj.toJSONString());}@RequestMapping("/{userId}/{msg}") // 将消息发送到/topic/greetings路径下public void sendUser(@PathVariable String userId,@PathVariable String msg) {//创建业务消息信息JSONObject obj = new JSONObject();obj.put("msg", msg);//消息内容webSocket.sendOneMessage(userId, obj.toJSONString());}}
3、前端环境搭建
前端是基于Vue实现,具体代码如下:
<template><div class="order-list"><span>TestMsg:{{ message }}</span></div>
</template>
<script>
export default {name: 'HomeView',data() {return {message:''}},components: {},created() {},mounted() {//初始化websocketthis.initWebSocket()},destroyed: function () { // 离开页面生命周期函数this.websocketclose();},computed: {},methods: {initWebSocket: function () { // 建立连接var userId = "test"//this.COMMON.getStorage("user");//对应@ServerEndpoint("/api/websocket/{userId}")中的地址var url = "ws://ip:port/项目名/api/websocket/" + userId;this.websock = new WebSocket(url);this.websock.onopen = this.websocketonopen;this.websock.send = this.websocketsend;this.websock.onerror = this.websocketonerror;this.websock.onmessage = this.websocketonmessage;this.websock.onclose = this.websocketclose;},// 连接成功后调用websocketonopen: function () {console.log("WebSocket连接成功");},// 发生错误时调用websocketonerror: function (e) {console.log("WebSocket连接发生错误" + JSON.stringify(e));},// 给后端发消息时调用websocketsend: function (e) {console.log("WebSocket连接发生错误" + JSON.stringify(e));},
// 接收后端消息// vue 客户端根据返回的cmd类型处理不同的业务响应websocketonmessage: function (e) {this.message = data;},// 关闭连接时调用websocketclose: function (e) {console.log("connection closed (" + e.code + ")");}},}
</script>
<style lang="scss"></style>
4、测试
至此,我们就完成了WebSocket的服务端和前端的环境搭建,首先启动后台服务,然后启动前端服务,进入上述页面,这个时候就会建立起来链接,然后访问“http://localhost:8803/qriver-lab/api/msg/test/6666”,其中test对应的是userId,6666是msg信息,这个时候就会发现页面会自动显示6666,不需要进行刷新。
相关文章:

基于SpringBoot + Vue的项目整合WebSocket的入门教程
1、WebSocket简介 WebSocket是一种网络通信协议,可以在单个TCP连接上进行全双工通信。它于2011年被IETF定为标准RFC 6455,并由RFC7936进行补充规范。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性…...
AI智能机器人的语音识别是如何实现的 ?
什么是智能语音识别系统?语音识别实际就是将人类说话的内容和意思转化为计算机可读的输入,例如按键、二进制编码或者字符序列等。与说话人的识别不同,后者主要是识别和确认发出语音的人并非其中所包含的内容。语音识别的目的就是让机器人听懂…...

RabbitMQ: 死信队列
一、在客户端创建方式 1.创建死信交换机 2.创建类生产者队列 3.创建死信队列 其实就是一个普通的队列,绑定号私信交换机,不给ttl,给上匹配的路由,等待交换机发送消息。 二、springboot实现创建类生产者队列 1.在消费者里的…...
232 - Crossword Answers (UVA)
这道题因为我把puzzle打成了Puzzle,卡了我很久…………真的太无语了。 题目链接如下: Online Judge 我的代码如下: #include <cstdio> #include <cctype> #include <set> const int maxx 10;int r, c, kase, cnt, tem…...
MySQL表结构设计规范
一、表设计 1. 命名规范 表名由小写英文字母和下划线组成表必须填写描述信息表名中的英文单词应该使用单数形式临时表以 tmp 为前缀,以日期为后缀备份表以 bak 为前缀,以日期为后缀使用hash、md5 进行散表,表名后缀使用16进制 2. 设计规范…...

如何利用ProcessOn 做资产管理流程图
资产管理 是一家公司最重要的管理活动。好的资产管理可以让资源最优化利用,实现资产价值的最大化。可以帮助组织管理和降低风险。同时当需要决策的时候,对资产数据进行分析和评估,也可以帮助做出更明智的决策,如优化资产配置、更新…...

geopandas 笔记:geometry上的操作汇总
如无特殊说明,数据主要来自:GeoDataFrame 应用:公园分布映射至subzone_UQI-LIUWJ的博客-CSDN博客 0 读入数据 subzone gpd.read_file(ura-mp19-subzone-no-sea-pl.geojson) subzone subzone_tstsubzone[0:5] subzone_tst subzone_tst.plot…...

【MongoDB】Ubuntu22.04 下安装 MongoDB | 用户权限认证 | skynet.db.mongo 模块使用
文章目录 Ubuntu 22.04 安装 MongoDB后台启动 MongoDBshell 连入 MongoDB 服务 MongoDB 用户权限认证创建 root 用户开启认证重启 MongoDB 服务创建其他用户查看用户信息验证用户权限删除用户 skynet.db.mongo 模块使用authensureIndexfind、findOneinsert、safe_insertdelete、…...

Python对象序列化
迷途小书童的 Note 读完需要 7分钟 速读仅需 3 分钟 大家好,我是迷途小书童! 在 Python 开发中,我们经常需要将对象数据保存到磁盘,或者通过网络传输对象信息。这时就需要序列化,Pickle 库为我们提供了极为方便的对象序…...

jmeter 准确的吞吐量定时器 Precise Throughput Timer
准确的吞吐量定时器使用实例 提取码:gpex: 说明:配置10个线程,每个线程请求200次,通过准确地的定时器模拟QPS为20的场景 配置测试接口参考链接 配置jmeter测试脚本,主要关注准确的吞吐量定时器参数配置 目…...

后端/DFT/ATPG/PCB/SignOff设计常用工具/操作/流程及一些文件类型
目录 1.PD/DFT常用工具及流程 1.1 FC和ICC2 1.2 LC (Library compiler) 1.3 PrimeTime 1.4 Redhawk与PA 1.5 Calibre和物理验证PV 1.6 芯片设计流程 2.后端、DFT、ATPG的一些常见文件 2.1 LEF和DEF 2.2 ATPG的CTL和STIL 2.3 BSDL 2.4 IPXCT 3.PCB设计的一些工作和工…...

jvm 程序计算器 程序计数器是否溢出 程序计数器是做什么的 java程序计数器会内存溢出吗 程序计数器作用与用处 jvm内存模型 jvm合集(一)
1. jvm内存模型: 内存模型: 程序计数器 堆 栈 本地方法栈 方法区 2. java代码编译为class文件,由类加载器加载到jvm,然后由解释器,jit即时编译到机器码,机器码再到cpu执行 3. 程序计数器: 是一块较小的内存…...

关于近期小程序测试的常见漏洞演示
本章节将为大家介绍一下小程序常见的漏洞的展示案例,包括支付业务逻辑漏洞、任意用户登录漏洞、水平越权漏洞等高危漏洞。 以上小程序测试均获取授权,并且客户均已得到修复(仅供学习,请勿恶意攻击) 关于微信小程序如何拦截数据包ÿ…...
磐基2.0部署apisix集群
一、部署etcd集群 由于etcd是磐基2.0的组件服务,直接通过组件部署即可。如需手动部署,参考如下链接 k8s 部署etcd集群_k8s部署etcd_平凡似水的人生的博客-CSDN博客前言公司计划使用etcd来做统一配置管理,由于服务都在阿里云托管k8s集群上&a…...
Python requests爬虫豆瓣图片返回数据为空。
爬个豆瓣图片,记录个小问题,发现爬取豆瓣原图的时候拿不到数据,返回为空,爬小图可以,爬其他网站的也都正常,最后发现是header中If-Modified-Since这个参数的原因,加上了就拿不到数据,…...
【Spring事务的实现原理】
Spring事务的实现原理就是通过拦截Transactional注解标识的方法,使用事务增强器对这些方法进行事务管理。其中关键的是事务管理器和事务属性源的配置和使用。Spring事务的实现原理可以简单理解为以下几个步骤: 从配置文件中获取PlatformTransactionManag…...

摆动输入连杆夹持机构
1、运动与受力分析 import sympy as sy import numpy as np import matplotlib.pyplot as plt a,a1,b,b1,c,c1,d2,d3,fi,F,L,e sy.symbols(a,a1,b,b1,c,c1,d2,d3,fi,F,L,e)A(-d2,0) D(0,d3) B(-d2a*cos(fi),a*sin(fi)) C(-c*cos(pu),d3c*sin(pu)) B(-d2a*cos(fipi),a*sin(fipi…...

C++——类与对象(下篇)
前言 前面已经介绍了类与对象(上),类与对象(中)的两篇文章,下面是类与对象的最后一些重要知识点的介绍和总结。 目录 再谈构造函数Static成员友元内部类匿名对象拷贝对象时的一些编译器优化再次理解封装…...
stm32 freeRTOS lwip TCP快速发送,内存泄露问题
现象1: 发送缓慢,tcp_write之后要等200多ms才能过发送出去,而且粘包严重。 解决办法 tcp_write之后,立马调用tcp_output ,tcp就会立马发送。 tcp_write tcp_output 现象2: 持续快速发送和接受TCP数据出…...

Ei、Scopus双检索 | 2024年第三届人工智能与机器学习前沿国际会议(FAIML 2024)
会议简介 Brief Introduction 2024年第三届人工智能与机器学习前沿国际会议(FAIML 2024) 会议时间:2024年4月26日-28日 召开地点:中国宜昌 大会官网:www.faiml.org FAIML 2024将围绕“人工智能与机器学习”的最新研究领域而展开,为…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...