js使用websocket,vue使用websocket,copy即用

news/2024/7/8 15:35:45 标签: javascript, websocket, 开发语言

 新建一个文件 websocket.js

javascript">// 定义websocket 地址
let socketurlDev = "ws://192.000.0.0:8085/websocket/admin/"; //开发环境
let socketurlProd = "wss://123456789.cn/prod-api/websocket/admin/"; //正式环境

// 重连锁, 防止过多重连
let reconnectLock = false;
// 定义一个消息发送中(包含发送失败的)的字典
window.messageSendingDic = {};
// 定义一个消息websocket连接状态的字段, 并且要绑定到widow上, 方便调用
// 0 未连接, 1 连接成功 2 连接中
window.webSocketState = 0;

// 定义连接服务器方法
function connectWebsocket(tenantInfo){
    console.log("tenantInfo",tenantInfo)
    //如果用户已登录, 进行连接websoket, 如果没有登陆, 登录后进行连接 用token判断
    // 创建一个websocket连接
    // let webSocket = new WebSocket(socketurl);
    
    // 如果想要传token, 因为ws不支持通过设置header, 所以直接在地址中加参数, 
    let socketurl= ''
    if (process.env.NODE_ENV === 'production') {  // 生产环境下的配置
        socketurl =  `${socketurlProd}${tenantInfo.tenantId}`
    } else if (process.env.NODE_ENV === 'development') {// 开发环境下的配置
        socketurl = `${socketurlDev}${tenantInfo.tenantId}`
    } else if (process.env.NODE_ENV === 'test') {// 测试环境下的配置
        socketurl =  `${socketurlDev}${tenantInfo.tenantId}`
    }

    let webSocket = new WebSocket(socketurl);
    // 监听webSocket的各个状态
    // 连接成功
    webSocket.onopen = function() {
        console.log("websocket连接成功")
        // 连接成功后将连接状态改变
        window.webSocketState = 1;
        // 连接成功后, 要将消息队列里面的消息重新发送出去(底层重发, 和页面无关)
        for(let session in window.messageSendingDic){
            session.forEach(message => {
                // 重发消息
                reSendMessage(message)
            });
       }
    }
    // 连接出错
    webSocket.onerror = function(error){
        console.log("websocket连接出错", error);
        // 进行重连
        reconnectWebsocket();
    }

    // 连接关闭
    webSocket.onclose = function(result){
        console.log("websocket连接关闭", result);
        if(result == "退出登录"){
            return
        }
        // 进行重连
        reconnectWebsocket();
    }

    // 接受到消息
    webSocket.onmessage = function(message){
        console.log("websocket接受到消息", message);
        // 将受到的消息进行分类, 分发处理
        formatAcceptMessage(message)
    } 
    // 将webSocket绑定到window上面, 方便后续调用
    window.webSocket = webSocket;
}

// 定义重连方法 如果连接失败, 或者关闭, 
function reconnectWebsocket(){
    // 如果正在重连, 则返回
    if(reconnectLock){
        return;
    }
    // 进行加锁
    reconnectLock = true;
    // 重连时将连接状态改变
    window.webSocketState = 2;
    // 为了防止过多请求, 1s后进行重连
    setTimeout(function(){
        // 解锁
        reconnectLock = false;
        // 进行连接, 如果失败接着重连
        // connectWebsocket();
    }, 1000)

}
/**
 * 关闭websocket 退出时会用到
 *
 */
function closeWebsocket(){
    window.webSocket.onclose("退出登录")
}
// 定义发送消息的方法 message 格式为json
/**
 * 
 * @param {
 *      message: "内容",
 *      id: "xxxxxxx"
 * } message 消息内容
 * @param "1" messageType 消息类型
 * @param "QueryMsg" messageClass 附加字段吗消息类, 这里是以protobufjs的消息类为例
 */
function sendMessage(message, messageType, messageClass) {
    // 这里可以对message做一些格式化处理
    let formaterMessge = message;

    // 将消息添加到发送中的数组中进行记录
    // 先判断该回话有没有对应的数组, 如果没有就创建, 在添加, 如果有直接添加
    if(window.messageSendingDic[message.sessionId]) {
        window.messageSendingDic[message.sessionId].push(formaterMessge);
    } else {
        window.messageSendingDic[message.sessionId] = [];
        window.messageSendingDic[message.sessionId].push(formaterMessge);
    }
    // 如果websocket连接成功, 进行发送消息
    if(window.webSocketState == 1) {
        formaterMessge = JSON.stringify(formaterMessge)
        // 这里就可以直接用window调用了
        window.webSocket.send(formaterMessge);
    } else {
        // 如果websocket没有连接成功, 直接告诉消息发送页面消息发送失败, 模拟接受到消息, 发给对应页面
        let formaterMessge = {};
        // 将处理后的消息进行发送通知, 通知给需要的页面进行处理, 在需要的页面进行监听 
        // 注意: 使用页面添加window.addEventListener("acceptNewMessage", this.testAction)
        window.dispatchEvent(new CustomEvent("acceptNewMessage", formaterMessge));
    }
}

// 定义重发送消息的方法 message 格式为json
/**
 * 
 * @param {
*      message: "内容",
*      id: "xxxxxxx"
* } message 消息内容
* @param "1" messageType 消息类型
* @param "QueryMsg" messageClass 附加字段吗消息类, 这里是以protobufjs的消息类为例
*/
function reSendMessage(message) {
   // 如果websocket连接成功, 进行发送消息
   if(window.webSocketState == 1) {
       // 这里就可以直接用window调用了
       window.webSocket.send(message);
   } 
}

// 定义收到消息进行消息解析的方法
function formatAcceptMessage(message) {
    // 处理消息. 格式化
    let formaterMessge = message;
    // 将发送成功的消息从发送中移除
    if(window.messageSendingDic[message.sessionId]) {
        let sendingArray = window.messageSendingDic[message.sessionId];
        // 过滤发送成功的
        window.messageSendingDic[message.sessionId] = sendingArray.filter(msg => {
            return msg.id != message.id
        });
    } 
    // 将处理后的消息进行发送通知, 通知给需要的页面进行处理, 在需要的页面进行监听 
    // 注意: 使用页面添加window.addEventListener("acceptNewMessage", this.testAction)
    // CustomEvent 必须使用detail为参数
    window.dispatchEvent(new CustomEvent("acceptNewMessage",{
            detail:formaterMessge
        }
    ));
}

// 如果服务器端有消息确认, 可以根据消息确认, 添加消息是否发送成功的状态, 
// 需要单独创建一个数组, 用来存放发送中的数据(包含发送失败的数据)


module.exports = {
    connectWebsocket,
    sendMessage
}

使用

javascript">    import {connectWebsocket,sendMessage} from "@/utils/websocket.js" 
  
    //开始连接 
    connectWebsocket({tenantId:123})

    //发送消息
    sendMessage("需要发送的内容")

    // 这里监听收到的消息
    window.addEventListener("acceptNewMessage", (event)=>{
      this.message = event.detail.data
      console.log("acceptNewMessage",event.detail.data)
    })


http://www.niftyadmin.cn/n/5537325.html

相关文章

qt 关于大端小端的一个实验 简单实验

1.概要 起因我用滚动是x86电脑,我用一个usort a11a ,我期待转换长的char字符应该是这样的“1aa1”,因为x86是小端的,这也是这个16位 类型的实际内存顺序,但是输出的结果是 “a11a”,难道这环境不是小端?难道qt能智能…

【Unix/Linux】$bash-3.2是什么

bash-3.2 指的是Bourne Again Shell(Bash)的3.2版本。 Bash是一个广泛使用的Unix shell和命令语言,是GNU项目的一部分,也是许多Linux发行版和Unix系统的默认shell。 以下是一些关于Bash 3.2的要点: 1. 兼容性&#…

---java KMP算法---

对于在一段字符串中查找一段字符串,如果用数组遍历的方法那就效率低下,所以产生了效率更高的KMP算法 KMP算法查只需要遍历一次字符串就可以找出第一次出现的目标字符串 要学的话建议区b站看视频,学着由视频学者比较容易 我这里就提供下我实…

初学vue3与ts:获取组件ref实例

/*** 获取组件ref* param {VueComponentIns} 组件实例* returns 组件ref*/ // eslint-disable-next-line export function useCompRef<T extends abstract new (...args: any) > any>(_: T) {return ref<InstanceType<T>>(); }使用 <a-com ref"a…

echarts实现3D柱状图(视觉层面)

一、第一种效果 效果图 使用步骤 完整实例&#xff0c;copy就可直接使用 <template><div :class"className" :style"{height:height,width:width}" /> </template><script>import echarts from echartsrequire(echarts/theme/…

如何在Vue中添加事件监听器

在Vue中添加事件监听器主要有两种方式&#xff1a;在模板中直接添加和使用Vue实例的方法。以下将详细解释这两种方法。 1. 在模板中直接添加 在Vue的模板中&#xff0c;你可以直接在HTML元素上使用v-on指令&#xff08;或其简写形式&#xff09;来监听DOM事件&#xff0c;并在…

Keycloak SSO 如何验证已添加的 SPN 是否生效

使用 Kerberos Ticket 验证&#xff1a; 在客户端计算机上&#xff0c;运行以下命令以获取 Kerberos Ticket&#xff1a; klist检查是否存在与 HTTP/yourdomain.com 相关的票证。如果存在&#xff0c;说明 SPN 已生效。 测试应用程序&#xff1a; 使用具有 HTTP/yourdomain.com…

elasticsearch入门基本知识+使用案例

1、ES逻辑结构 索引-index&#xff1a;相当于db中的数据库名。索引命名规则&#xff1a;小写字母。 类型-type&#xff1a;相当于数据库中的表名&#xff0c;为具有相同字段的文档定义的一个类型。 字段-field&#xff1a;相当于表字段名&#xff0c;文档数据的属性…