Vue3(pinia) 整合 SpringWebsocket链接url动态传参

前言
👏作者简介:我是笑霸final,一名热爱技术的在校学生。
📝个人主页:个人主页1 || 笑霸final的主页2
📕系列专栏:java专栏
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,👍点赞👍 + 👀关注👀 + 🤏收藏🤏

目录

  • 一.环境准备
  • 二.vue代码
  • 三.SpringWebsocket相关理论
    • 3.1 AbstractWebSocketHandler
    • 3.2 HttpSessionHandshakeInterceptor
    • 3.3 WebSocketConfigurer
  • 四.spring boot代码
    • 4.1继承AbstractWebSocketHandler
    • 4.2 实现WebSocketConfigurer

一.环境准备

vue3 :官方文档 https://cn.vuejs.org/
pinia:官方文档 https://pinia.vuejs.org/zh/
springWebSocket的maven坐标

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

二.vue代码

pinia的安装和使用就不说了直接看官方文档就行。

1、创建stores/demo.ts

import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useChantStore = defineStore('chant', () => {
  //state
  const msg = ref("")//发送的消息
  var socket= ref() ;
  const userId = ref("")  //传递的参数
  const count = ref(0)  	//链接标志

  //action
  // Websoket连接成功事件
  const websocketonopen = (res: any) => {
    console.log("WebSocket连接成功", res);
  };
  // Websoket接收消息事件
  const websocketonmessage = (res: any) => {
    console.log("数据", res);
    msg.value = res.data

  };
  // Websoket连接错误事件
  const websocketonerror = (res: any) => {
    console.log("连接错误", res);
  };
  // Websoket断开事件
  const websocketclose = (res: any) => {
    console.log("断开连接", res);
    websocketclose;
    // 销毁 websocket 实例对象
    socket.value = null;
    count.value = 0;
    userId.value = '';
  };

  //创建链接
  const connectWebSocket = () =>{
    console.log("websocket创建链接 usrid= ",userId.value);
    const wsurl = `ws://127.0.0.1:8888/api/myWs1?userId=${userId.value}`;
    socket.value = new WebSocket(wsurl);
    socket.value.onopen = websocketonopen;
    socket.value.onmessage = websocketonmessage;
    socket.value.onerror = websocketonerror;
    socket.value.onclose = websocketclose;
    count.value = 1;
  }
  //关闭链接
  const closetWebSocket = () =>{
    websocketclose;
    // 销毁 websocket 实例对象
    socket.value = null;
    count.value = 0;
    userId.value = '';

  }
  

  return { msg, socket,userId,count,connectWebSocket,closetWebSocket }
})

二、在使用的组件中使用

import { useChantStore } from '../stores/chant'
//websocket
const chantWebSocket = useChantStore()
//你自己的代码

三.SpringWebsocket相关理论

主要的接口

在这里插入图片描述

3.1 AbstractWebSocketHandler

AbstractWebSocketHandler:是 Spring Framework 中用于处理 WebSocket 通信的一个基础抽象类,它位于 org.springframework.web.socket.handler 包下。在构建基于Spring的WebSocket应用时,开发者可以扩展这个类来创建自定义的消息处理器。

  • 连接建立与关闭处理

    • void afterConnectionEstablished(WebSocketSession session):当一个新的WebSocket连接建立后,此方法会被调用,开发者可以在其中进行初始化操作或者订阅事件。
    • void handleTransportError(WebSocketSession session, Throwable exception):当在传输层发生错误时调用,可用于处理异常情况和清理资源。
    • void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus):在WebSocket连接关闭后执行,通常用来清理资源或记录日志。
  • 消息处理

    void handleMessage(WebSocketSession session, WebSocketMessage<?> message):这是一个抽象方法,子类需要实现它来处理从客户端接收到的各种类型的消息。

  • 握手协商:

    可以通过重写 boolean supportsPartialMessages() 来表明是否支持分片消息。

  • 其他功能:

    它还可能提供一些便利的方法用于发送消息给客户端、设置会话属性等。

3.2 HttpSessionHandshakeInterceptor

HttpSessionHandshakeInterceptor 是 Spring Framework 中用于 WebSocket 扩展的一个类,它继承自 HandshakeInterceptor 接口,并特别关注于在 WebSocket 握手阶段与 HTTP HttpSession 的交互。

当客户端尝试建立 WebSocket 连接时,会触发一个握手过程,在这个过程中,服务器可以使用 HttpSessionHandshakeInterceptor 来拦截握手请求和响应,以便进行额外的检查、修改握手参数或执行特定的业务逻辑。
通过实现或扩展 HttpSessionHandshakeInterceptor 类,开发人员能够定制WebSocket连接初始化的过程,比如进行权限验证、会话同步以及对跨域支持等需求的处理。

HttpSessionHandshakeInterceptor 提供了两个核心方法

  • beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes):

    • 在握手开始前调用,允许开发者检查HTTP请求并决定是否应该继续握手。
    • 可以从HTTP请求中获取当前的HttpSession,并将需要的数据复制到WebSocketSession的属性中。
    • 可以通过修改attributes参数来添加或删除即将传递给WebSocketSession的属性。
    • 如果返回false,则会中断握手,即拒绝建立WebSocket连接。
  • afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception):

    • 在握手成功完成后调用,无论握手是否成功,都会执行此方法(如果握手失败,则exception参数将包含相关异常)。
    • 通常在此处用于清理资源、记录日志或者进行其他后处理操作。

3.3 WebSocketConfigurer

WebSocketConfigurer 是 Spring Framework 中用于配置 WebSocket 功能的接口,它允许开发者自定义 WebSocket 服务端点(endpoint)的行为和路由规则。该接口位于 org.springframework.web.socket.config.annotation 包下,是 Spring WebSocket 支持的核心部分。

在基于 Spring Boot 构建 WebSocket 应用程序时,通过实现 WebSocketConfigurer 接口或使用其子接口如 DelegatingWebSocketMessageBrokerConfiguration 等,可以方便地配置 WebSocket 的核心功能:

  • 注册 WebSocketHandler:

    开发者可以通过实现 WebSocketConfigurer 中的相应方法来注册处理 WebSocket 连接请求的 WebSocketHandler 实例。这些 Handler 负责与客户端进行双向通信,包括消息接收、处理和发送。

  • 配置访问路径:

    可以设置 WebSocket 的入口地址,即客户端通过哪个 URL 建立 WebSocket 连接。

  • 跨域支持:

    配置是否允许来自不同源的 WebSocket 请求,即 CORS (Cross-Origin Resource Sharing) 政策。

  • 定制握手过程:

    添加 HandshakeInterceptor 实例,以便在 WebSocket 握手阶段执行额外的验证逻辑或操作。

  • 会话管理:

    定义如何管理 WebSocketSession,例如设置超时策略等。

四.spring boot代码

4.1继承AbstractWebSocketHandler

@Slf4j
@Component
public class MyWsHandler extends AbstractWebSocketHandler {

    //保存已经链接的用户
    private static Map<String, WsSessionBean> wsSessionBeanMap;

    static {
        wsSessionBeanMap = new ConcurrentHashMap<>();
    }

    /**
     * //建立链接
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);

        //过去ur中的参数
        URI uri = session.getUri();
        UriComponents components = UriComponentsBuilder.fromUri(uri).build();

        MultiValueMap<String, String> queryParams = components.getQueryParams();
        String userId = queryParams.getFirst("userId");

        WsSessionBean wsSessionBean = new WsSessionBean(Integer.valueOf(userId), session);

        wsSessionBeanMap.put(session.getId(), wsSessionBean);

        log.info("建立链接了。。。。。{}", wsSessionBean);

    }


    //收到消息
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        super.handleMessage(session, message);
        log.info("当前session信息:{}", session);
        log.info("消息是:message:{}", message.getPayload());
        //广播消息===========================自己实现的代码,用来发送消息
        sendMessageToBroadcast(session.getId(), message.getPayload().toString());

    }
/**
     * 发送消息到所有客户端 (广播消息 发给当前用户得所有好友)
     *
     * @param userId      当前用户sessionId
     * @param messageText 当前用户要发送得内容
     */
    public void sendMessageToBroadcast(String userId, String messageText) {
        wsSessionBeanMap.forEach((k, v) -> {
            if (!k.equals(userId)) {//说明要发得对象
                WebSocketSession targetSession = v.getSession();
                if (targetSession != null && targetSession.isOpen()) {
                    TextMessage textMessage = new TextMessage(messageText);
                    try {
                        targetSession.sendMessage(textMessage);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                } else {
                    log.info("无法向用户{}发送消息,会话未建立或已关闭", userId);
                }
            }
        });
    }

    /**
     * 传输异常
     *
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);
        if (session.isOpen()) {
            session.close();
            wsSessionBeanMap.remove(session.getId());
        }
        log.info("传输异常");

    }

    /**
     * 链接关闭
     *
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        super.afterConnectionClosed(session, status);
        wsSessionBeanMap.remove(session.getId());
        log.info("链接关闭");
    }

    
}

4.2 实现WebSocketConfigurer

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Resource
    private MyWsHandler myWsHandler;
    @Bean
    public HandshakeInterceptor httpSessionHandshakeInterceptor() {
        return new HttpSessionHandshakeInterceptor();
    }
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWsHandler,"/myWs1")
                .setAllowedOrigins("*");
    }
}

欢迎大家👍点赞👍 + 👀关注👀 + 🤏收藏🤏 如有不足请指正

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

轧辊品质检测 直线度测量仪满足多种数据监测!

轧辊有带钢轧辊、型钢轧辊、线材轧辊、开坯辊、粗轧辊、精轧辊、破鳞辊、穿孔辊、平整辊、钢轧辊、铸铁轧辊、硬质合金轧辊、陶瓷轧辊等&#xff0c;但不管哪种类型的轧辊&#xff0c;对直线度测量都可以通过直线度测量仪来实现&#xff0c;这种测量仪检测方便&#xff0c;数据…

现货黄金贵金属投资难不难做?

现货黄金投资的难度因人而异&#xff0c;它涉及市场知识、分析能力、资金管理和心理素质等多个方面&#xff0c;因此不能一概而论。但是&#xff0c;如果投资者能够系统地学习相关知识&#xff0c;并在实践中不断积累经验&#xff0c;那么现货黄金投资并非难以驾驭。 先了解现货…

《汇编语言》- 读书笔记 - 第13章-int 指令

《汇编语言》- 读书笔记 - 第13章-int 指令 13.1 int 指令13.2 编写供应用程序调用的中断例程中断例程&#xff1a;求一 word 型数据的平方主程序中断处理程序执行效果 中断例程&#xff1a;将一个全是字母&#xff0c;以0结尾的字符串&#xff0c;转化为大写主程序中断处理程序…

作业1-224——P1927 防护伞

思路 遍历一下找到两点间的最远距离&#xff0c;直接公式算结果&#xff0c;控制输出位数 参考代码 #include<iostream> #include<iomanip> #include<cmath> using namespace std; int main() { int n; cin>>n; int x[n],y[n]; do…

hive报错:FAILED: NullPointerException null

发现问题 起因是我虚拟机的hive不管执行什么命令都报空指针异常的错误 我也在网上找了很多相关问题的资料&#xff0c;发现都不是我这个问题的解决方法&#xff0c;后来在hive官网上与hive 3.1.3版本相匹配的hadoop版本是3.x的版本&#xff0c;而我的hadoop版本还是2.7.2的版本…

5G 网络建设【华为OD机试-JAVAPythonC++JS】

题目描述 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N&#xff0c;接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通&#xff0c;不同基站之间架设光纤的成本各不相同&#xff0c;且有些节点之间已经存在光纤相…

WIN10 无密码自动登录

1、家里重装了一下WIN10系统&#xff0c;第一次登陆居然用了微软网站账号&#xff0c;结果密码忘记了&#xff0c;后面只能用PIN码登陆系统。 2、需要登录微软的网站修改密码&#xff1a; Microsoft account | Sign In or Create Your Account Today – Microsoft 3、在运行…

赵本山与高秀敏夫妇本想找范伟要那1200元电视机垫款,却不好意思向范伟开口--小品《面子》(中1)的台词

赵本山与高秀敏夫妇本想找范伟要那1200元电视机垫款&#xff0c;却不好意思向范伟开口 --小品《面子》&#xff08;中1&#xff09;的台词 表演者&#xff1a;赵本山 高秀敏 范伟 &#xff08;接上&#xff09; 高秀敏&#xff1a;咱俩抓紧提事啊 赵本山&#xff1a;不着急…

div在vue的组件之中如何设置这个字体的颜色和样式大小

在Vue组件中设置<div>的字体颜色和样式大小可以通过两种主要方式实现&#xff1a;通过内联样式&#xff08;inline styles&#xff09;或者通过CSS类&#xff08;CSS classes&#xff09;。 使用内联样式 在Vue模板中直接在元素上使用style属性来设置样式。这种方法适用…

上云还是下云,最大挑战是什么?| 对话章文嵩、毕玄、王小瑞

近半年来&#xff0c;公有云领域频频发生阿里云、滴滴等平台崩溃事件&#xff0c;与此同时&#xff0c;马斯克的“X 下云省钱”言论引起了广泛关注&#xff0c;一时间&#xff0c;“上云”和“下云”成为热议话题。在最近举办的 AutoMQ 云原生创新论坛上&#xff0c;AutoMQ 联合…

【GPU驱动开发】- AST简介

前言 不必害怕未知&#xff0c;无需恐惧犯错&#xff0c;做一个Creator&#xff01; AST&#xff0c;抽象语法树&#xff0c;是一种包含丰富语义信息的格式&#xff0c;其中包括类型、表达式树和符号等。 TranslationUnitDecl&#xff1a;该类表示一个输入源文件 ASTContext&…

通辽文化瑰宝沈阳展,文物预防性保护成亮点

灿烂的历史瑰宝&#xff0c;从通辽草原远道而来&#xff0c;于沈阳博物馆内熠熠生辉。展览汇聚了非常多的历史文物&#xff0c;每一件都承载着深厚的文化底蕴和民族记忆。但是&#xff0c;文物的易损性变成一个大问题。为了确保这些历史财产可以在最佳状态下向群众展现&#xf…

如何在腾讯云上快速部署幻兽帕鲁/Palworld服务器?

如何在腾讯云上快速部署幻兽帕鲁/Palworld服务器&#xff1f; 准备工作&#xff1a;首先需要准备腾讯云账号和Steam账号。腾讯云账号适用于新老用户&#xff0c;而Steam账号则是因为幻兽帕鲁是一款Steam平台的游戏。此外&#xff0c;还需要购买一台腾讯云服务器&#xff0c;推荐…

一线互联网架构师筑基必备技能之Android篇,快速从入门到精通

真正最能锻炼能力的便是直接去阅读源码&#xff0c;不仅限于阅读Android系统源码&#xff0c;还包括各种优秀的开源库。 由于整个文档比较全面&#xff0c;内容比较多&#xff0c;篇幅不允许&#xff0c;下面以截图方式展示 。 深入解析微信 MMKV 源码 初始化获取修改删除读取…

Java-常用集合

Jva常用集合 一、Java 集合框架体系二、Collection接口和方法1. List接口List 接口主要实现类&#xff1a;ArrayListList 的实现类之二&#xff1a;LinkedListList 的实现类之三&#xff1a;Vector 2. Set接口Set 主要实现类&#xff1a;HashSetSet 实现类之二&#xff1a;Link…

在UniApp中引入大于40kb字体包的记录

因为项目UI需要特殊字体&#xff0c;所以给了一个80kb字体包&#xff0c;但是在正常的使用导入时候发现不生效 这是我的导入过程 1.把下载好的文件放入static/font目录中 2.在app.vue中引用 font-face { font-family: zitiming; src: url(/static/font/YouSheBiaoTiHei-2.t…

【打工日常】使用docker部署在线PDF工具

一、Stirling-PDF介绍 Stirling-PDF是一款功能强大的本地托管的基于 Web 的 PDF 操作工具&#xff0c;使用 docker部署。该自托管 Web 应用程序最初是由ChatGPT全权制作的&#xff0c;现已发展到包含广泛的功能来处理您的所有 PDF 需求。允许对 PDF 文件执行各种操作&#xff0…

Flutter中的三棵树

Widget Tree&#xff1a; 页面配置信息。 Element Tree&#xff1a; Widget tree的实例化对象&#xff0c;创建出renderObject&#xff0c;并关联到element.renderobject属性上&#xff0c;最后完成RenderObject Tree的创建。 RenderObject Tree&#xff1a;完成布局和图层绘制…

HTML---表单验证

文章目录 目录 本章目标 一.表单验证概述 二.表单选择器 属性过滤选择器 三.表单验证 表单验证的方法 总结 本章目标 掌握String对象的用法会使用表单选择器的选择页面元素会使用JQuery事件进行表单验证Ajax的概念和作用 一.表单验证概述 前端中的表单验证是在用户提交表…

【多线程】常见锁策略详解(面试常考题型)

目录 &#x1f334; 乐观锁 vs 悲观锁&#x1f38d;重量级锁 vs 轻量级锁&#x1f340;自旋锁&#xff08;Spin Lock&#xff09;&#x1f38b;公平锁 vs ⾮公平锁&#x1f333;可重⼊锁 vs 不可重⼊锁&#x1f384;读写锁⭕相关面试题 常⻅的锁策略 注意: 接下来讲解的锁策略不…