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

 新建一个文件 websocket.js

// 定义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
}

使用

    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)
    })

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-09 17:10:04       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-09 17:10:04       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-09 17:10:04       57 阅读
  4. Python语言-面向对象

    2024-07-09 17:10:04       68 阅读

热门阅读

  1. PostgreSQL的扩展(extensions)-常用的扩展-pg_profile

    2024-07-09 17:10:04       26 阅读
  2. Spring Boot整合MongoDB实现事务管理

    2024-07-09 17:10:04       24 阅读
  3. Solana RPC 的工作原理

    2024-07-09 17:10:04       24 阅读
  4. 音频demo:使用faad2将AAC数据解码出PCM数据

    2024-07-09 17:10:04       24 阅读
  5. SQLAlchemy配置连接多个数据库

    2024-07-09 17:10:04       29 阅读
  6. Android C++系列:Linux常用函数和工具

    2024-07-09 17:10:04       23 阅读
  7. vb.net读取mssql的image字段后,如何转换成二进制

    2024-07-09 17:10:04       29 阅读
  8. 常用 Android 反编译工具apktooldex2jarenjarifyjd-guijadx

    2024-07-09 17:10:04       23 阅读
  9. Android Gradle 开发与应用 (十): Gradle 脚本最佳实践

    2024-07-09 17:10:04       27 阅读
  10. 牛客周赛 Round 50

    2024-07-09 17:10:04       36 阅读
  11. 量化机器人如何提高投资效率?

    2024-07-09 17:10:04       25 阅读
  12. Emacs相关

    2024-07-09 17:10:04       30 阅读