springBoot与Vue共同搭建webSocket环境

欢迎使用Markdown编辑器

你好! 这片文章将教会你从后端springCloud到前端VueEleementAdmin如何搭建Websocket

前端

1. 创建websocket的配置文件在utils文件夹下websocket.js

// 暴露自定义websocket对象
export const socket = {// 后台请求路径url: '',websocketCount: -1,// websocket对象websocket: null,// websocket状态websocketState: false,// 重新连接次数reconnectNum: 0,// 重连锁状态,保证重连按顺序执行lockReconnect: false,// 定时器信息timeout: null,clientTimeout: null,serverTimeout: null,// 初始化方法,根据url创建websocket对象封装基本连接方法,并重置心跳检测initWebSocket(newUrl) {socket.url = newUrlsocket.websocket = new WebSocket(socket.url)socket.websocket.onopen = socket.websocketOnOpensocket.websocket.onerror = socket.websocketOnErrorsocket.websocket.onmessage = socket.webonmessagesocket.websocket.onclose = socket.websocketOnClosethis.resetHeartbeat()},reconnect() {// 判断连接状态console.log('判断连接状态')if (socket.lockReconnect) returnsocket.reconnectNum += 1// 重新连接三次还未成功调用连接关闭方法if (socket.reconnectNum === 3) {socket.reconnectNum = 0socket.websocket.onclose()return}// 等待本次重连完成后再进行下一次socket.lockReconnect = true// 5s后进行重新连接socket.timeout = setTimeout(() => {socket.initWebSocket(socket.url)socket.lockReconnect = false}, 5000)},// 重置心跳检测resetHeartbeat() {socket.heartbeat()},// 心跳检测heartbeat() {socket.clientTimeout = setTimeout(() => {if (socket.websocket) {// 向后台发送消息进行心跳检测socket.websocket.send(JSON.stringify({ type: 'heartbeat' }))socket.websocketState = false// 一分钟内服务器不响应则关闭连接socket.serverTimeout = setTimeout(() => {if (!socket.websocketState) {socket.websocket.onclose()console.log('一分钟内服务器不响应则关闭连接')} else {this.resetHeartbeat()}}, 60 * 1000)}}, 3 * 1000)},// 发送消息sendMsg(message) {socket.websocket.send(message)},websocketOnOpen(event) {// 连接开启后向后台发送消息进行一次心跳检测socket.sendMsg(JSON.stringify({ type: 'heartbeat' }))},// 初始化websocket对象// window.location.host获取ip和端口,// process.env.VUE_APP_WEBSOCKET_BASE_API获取请求前缀// 绑定接收消息方法webonmessage(event) {// 初始化界面时,主动向后台发送一次消息,获取数据this.websocketCount += 1if (this.websocketCount === 0) {const queryCondition = {type: 'message'}socket.sendMsg(JSON.stringify(queryCondition))console.log('初始化界面时,主动向后台发送一次消息,获取数据')}const info = JSON.parse(event.data)switch (info.type) {case 'heartbeat':socket.websocketState = trueconsole.log(JSON.stringify(info))breakcase 'message':if (info.message === '成功') {this.$notify({title: '提示',message: '成功',type: 'success',duration: 0})} else {this.$notify({title: '提示',message: '上传失败:' + info.message,type: 'warning',duration: 0})}breakcase 'error':console.log('websocket:error')break}},websocketOnError(error) {console.log(error)console.log('websocket报错了' + error)socket.reconnect()},websocketOnClose() {console.log('websocke他关闭了')socket.websocket.close()}
}
2. 在main.js中引入配置文件,使websocket全局都能使用

import { socket } from './utils/websocket'
Vue.prototype.$socket = socket

3. 设置登陆时开启websocket连接,

this. s o c k e t . i n i t W e b S o c k e t ( ‘ w s : socket.initWebSocket( `ws: socket.initWebSocket(ws:{process.env.VUE_APP_WEBSOCKET_BASE_API}/websocket/` + this.loginForm.username
) 这句是开启websocket连接的。

// 登录方法
handleLogin() {this.$refs.loginForm.validate(valid => {if (valid) {this.loading = truethis.$store.dispatch('user/login', this.loginForm).then(() => {this.$router.push({ path: this.redirect || '/', query: this.otherQuery })this.$store.dispatch('user/addInfomation', this.infoMation)this.$socket.initWebSocket(`ws:${process.env.VUE_APP_WEBSOCKET_BASE_API}/websocket/` + this.loginForm.username)this.loading = false}).catch(() => {this.loading = false})} else {console.log('error submit!!')return false}})
},
4. 设置退出时关闭websocket连接

this.$socket.websocketOnClose()这句是关闭websocket连接的

 logout() {await this.$store.dispatch('user/logout')this.$socket.websocketOnClose()this.$router.push(`/login?redirect=${this.$route.fullPath}`)}

重点和需要配置的地方都在websocket.js里比如接收消息方法webonmessage

后端

1.引依赖
        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
2.写配置
package com.szc.material.analysisService.confg.WebSocket;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;@Configuration
public class WebSocketConfig   {/*** 	注入ServerEndpointExporter,* 	这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}
3.创建Websocket服务类(依据自己的业务去改@OnMessage方法)
package com.szc.material.analysisService.confg.WebSocket;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;import javax.security.auth.message.MessageInfo;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;/*** @author zhj* @ServerEndpoint:将目前的类定义成一个websocket服务器端,注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端* @OnOpen:当WebSocket建立连接成功后会触发这个注解修饰的方法。* @OnClose:当WebSocket建立的连接断开后会触发这个注解修饰的方法。* @OnMessage:当客户端发送消息到服务端时,会触发这个注解修改的方法。* @OnError:当WebSocket建立连接时出现异常会触发这个注解修饰的方法。* ————————————————* 版权声明:本文为CSDN博主「人人都在发奋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* 原文链接:https://blog.csdn.net/qq991658923/article/details/127022522*/
@Component
@Slf4j
@ServerEndpoint("/websocket/{userId}")
public class MyWebSocketHandler extends TextWebSocketHandler {/*** 线程安全的无序的集合*/private static final CopyOnWriteArraySet<Session> SESSIONS = new CopyOnWriteArraySet<>();/*** 存储在线连接数*/private static final Map<String, Session> SESSION_POOL = new HashMap<>();@OnOpenpublic void onOpen(Session session, @PathParam(value = "userId") String userId) {try {SESSIONS.add(session);SESSION_POOL.put(userId, session);log.info("【WebSocket消息】有新的连接,总数为:" + SESSIONS.size());} catch (Exception e) {e.printStackTrace();}}@OnClosepublic void onClose(Session session,@PathParam(value = "userId") String userId) {try {SESSIONS.remove(session);SESSION_POOL.remove(userId);log.info("【WebSocket消息】连接断开,总数为:" + SESSION_POOL.size());} catch (Exception e) {e.printStackTrace();}}@OnMessagepublic void onMessage(String message, @PathParam(value = "userId") String userId) {JSONObject jsonObject = JSON.parseObject(message);if("heartbeat".equals(jsonObject.get("type").toString())){Map<String,String> messageInfor=new HashMap<>();messageInfor.put("type","heartbeat");messageInfor.put("message","我收到了你的心跳");sendOneMessage( userId,messageInfor);log.info("【WebSocket消息】收到客户端消息:" + message);}}/*** 此为广播消息** @param message 消息*/public void sendAllMessage(String message) {log.info("【WebSocket消息】广播消息:" + message);for (Session session : SESSIONS) {try {if (session.isOpen()) {session.getAsyncRemote().sendText(message);}} catch (Exception e) {e.printStackTrace();}}}/*** 此为单点消息** @param userId  用户编号* @param message 消息*/public void sendOneMessage(String userId, Map<String,String> message) {Session session = SESSION_POOL.get(userId);if (session != null && session.isOpen()) {try {synchronized (session) {log.info("【WebSocket消息】单点消息:" + message.get("message"));session.getAsyncRemote().sendText(JSON.toJSONString(message));}} catch (Exception e) {e.printStackTrace();}}}/*** 此为单点消息(多人)** @param userIds 用户编号列表* @param message 消息*/public void sendMoreMessage(String[] userIds, String message) {for (String userId : userIds) {Session session = SESSION_POOL.get(userId);if (session != null && session.isOpen()) {try {log.info("【WebSocket消息】单点消息:" + message);session.getAsyncRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}}
4.在需要的地方进行调用

(1)先注入websocket服务类

    @AutowiredMyWebSocketHandler myWebSocketHandler;

(2)在方法中调用给前端发消息的方法

myWebSocketHandler.sendOneMessage(userId,messageInfor);

问题:

1.如果你在controller层调用了service层中身为异步的方法出现了HttpServeletrequst空指针你需要在controller层调用异步方法前加入下面的代码。

ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();RequestContextHolder.getRequestAttributes().setAttribute("request", request, RequestAttributes.SCOPE_REQUEST);RequestContextHolder.setRequestAttributes(servletRequestAttributes,true);//设置子线程共享

调用requst中的参数时必须使用下面的方法

 HttpServletRequest request2 = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();if( request2.getHeader(UserContext.USER_NAME)!=null){return Optional.of(request2.getHeader(UserContext.USER_NAME));}

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

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

相关文章

Android前台服务和通知

前台服务 Android 13及以上系统需要动态获取通知权限。 //android 13及以上系统动态获取通知权限 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {checkPostNotificationPermission(); } private void checkPostNotificationPermission() {if (ActivityCompat.chec…

信息检索与数据挖掘 | 【实验】排名检索模型

文章目录 &#x1f4da;实验内容&#x1f4da;相关概念&#x1f4da;实验步骤&#x1f407;分词预处理&#x1f407;构建倒排索引表&#x1f407;计算query和各个文档的相似度&#x1f407;queries预处理及检索函数&#x1f525;对输入的文本进行词法分析和标准化处理&#x1f…

【Docker】Dockerfile使用技巧

开启Buildkit BuildKit是Docker官方社区推出的下一代镜像构建神器&#xff0c;可以更加快速&#xff0c;有效&#xff0c;安全地构建docker镜像。 尽管目前BuildKit不是Docker的默认构建工具&#xff0c;但是完全可以考虑将其作为Docker&#xff08;v18.09&#xff09;的首选…

一个注解让 Spring Boot 项目接口返回数据脱敏

1 背景 需求是某些接口返回的信息&#xff0c;涉及到敏感数据的必须进行脱敏操作 2 思路 ①要做成可配置多策略的脱敏操作&#xff0c;要不然一个个接口进行脱敏操作&#xff0c;重复的工作量太多&#xff0c;很显然违背了“多写一行算我输”的程序员规范。思来想去&#xff…

css如何将border线加到元素内部,占内边距,不占外边距

要将边框线添加到元素的内部&#xff0c;可以使用CSS的box-sizing属性和内边距&#xff08;padding&#xff09;来实现。 首先&#xff0c;将元素的box-sizing属性设置为border-box。这会使元素的宽度和高度包括边框和内边距在内。例如&#xff1a; .element {box-sizing: bo…

软件工程与计算总结(二十三)软件工程职业基础

本系列最后一更&#xff0c;《软计》系列总结的大结局&#xff01;本栏目告一段落&#xff0c;之后会结合真题和练习题再发布新的总结~ 往期链接&#xff1a; 《软件工程与计算》总结 一.软件工程职业 1.行业的发展 20世纪50年代&#xff1a;计算机还是研究型机器&#xff…

C++中显示构造和隐式构造

截图来源于C primerplus 第六版。

tomcat的负载均衡、动静分离(nginx联动)

动静分离&#xff1a; 访问静态页面和动态页面分开 实现动态和静态页面负载均衡 实验5台虚拟机 一、动态负载均衡 3台虚拟机模拟&#xff1a; 代理服务器&#xff1a;30 tomcat动态页面&#xff1a;21、22 代理服务器&#xff1a; proxy_pass http://tomcat; proxy_set_h…

buuctf[HCTF 2018]WarmUp 1

题目环境&#xff1a; 发现除了表情包&#xff0c;再无其他F12试试发现source.php文件访问这个文件&#xff0c;格式如下&#xff1a;url/source.php回显如下&#xff1a;PHP代码审计&#xff1a; <?php highlight_file(__FILE__); class emmm {public static function ch…

GIS在地质灾害危险性评估与灾后重建中的实践技术应用及python机器学习灾害易发性评价模型建立与优化

地质灾害是指全球地壳自然地质演化过程中&#xff0c;由于地球内动力、外动力或者人为地质动力作用下导致的自然地质和人类的自然灾害突发事件。由于降水、地震等自然作用下&#xff0c;地质灾害在世界范围内频繁发生。我国除滑坡灾害外&#xff0c;还包括崩塌、泥石流、地面沉…

我们在 Linux 环境中用 C 编程时,如果对文件读写,Linux 会自动给文件加锁嘛?

先说结论&#xff0c;结论是不会 我写了一个这样的程序 #include <stdio.h> #include <unistd.h>int main() {const char* pathname "your_file_pathname.txt";FILE* file NULL;int count 100;if(access(pathname, F_OK) 0) {file fopen(pathname…

Onnx精度转换 FP32->FP16

Onnx精度转换 FP32->FP16 1、依赖包 onnxonnxmltools 2、转换 from onnxmltools.utils.float16_converter import convert_float_to_float16 from onnxmltools.utils import load_model,save_modelonnx_model load_model("model.onnx") fp16_model convert_…

C语言进阶第九课 --------动态内存管理

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

各种添加路由的方法

Linux 篇&#xff1a; ipv4: #添加到主机的路由 # route add –host 192.168.168.110 dev eth0 # route add –host 192.168.168.119 gw 192.168.168.1 #添加到网络的路由 # route add –net IP netmask MASK eth0 # route add –net IP netmask MASK gw IP # route add –n…

k8s-----19、Helm

Helm 1、引入2、概述2.1 重点2.2 V3版本的Helm2.2.1 与之前版本的不同之处2.2.2 V3版本的运行流程 3、安装和配置仓库、一些附带操作3.1 安装3.2 配置仓库3.3 常用命令3.4 添加helm的自动补齐 4、快速部署应用(weave应用)5、 自行创建Chart5.1 Chart目录内容解析5.2 简单安装部…

codeforces (C++ Haunted House)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、由题目可知&#xff0c;他想让我们判断交换相邻字符位置后将二进制转为十进制后&#xff0c;能否整除2的次方。能整除即输出需要交换的次数&#xff0c;不能则输出-1。&#xff08;例&#xff1a;输入3和010这组数据就…

论文学习:漏洞检测SnapVuln

SnapVuln SnapVuln是一种基于学习的漏洞检测方法&#xff0c;它应用多个针对特定漏洞的跨函数算法来识别源和汇点&#xff0c;以捕捉各种漏洞类型的精确程序语义。通过从源代码中提取跨函数的图形&#xff08;IG&#xff09;&#xff0c;SnapVuln可以综合使用PDG、CFG和调用图…

WebDAV之π-Disk派盘 +Polaris Office

推荐一款可以实现在Windows桌面PC,Mac,Android设备和iOS设备上同步的移动办公软件,还支持通过WebDAV添加葫芦儿派盘。Polaris Office是一款功能全面的办公自动化套件,软件集成了Word、Excel、幻灯片(PPT)、ODT等文档格式,并且可以完美兼容任何Microsoft Office,PDF,TXT或…

封装、继承、多态的概念

封装&#xff1a;将数据&#xff08;属性&#xff09;和函数&#xff08;操作&#xff09;合成一个整体&#xff0c;封装在类里面。 继承&#xff1a;派生与独立设计若干相关的类&#xff0c;前者工作量更少&#xff0c;重复的部分可以从基类继承来&#xff0c;不需要单独编程…

html web前端 登录,短信验证码登录

html web前端 登录&#xff0c;短信验证码登录 1&#xff0c;手机号码格式校验 2&#xff0c;按钮点击60秒倒计时&#xff0c;按钮限制点击 3&#xff0c;验证码/或密码长度校验&#xff08;被注释&#xff0c;公司发的验证码长度不一致&#xff0c;不一定是6位&#xff09; 4…