在vue和uniapp中使用 websocket并封装js

vue中

websocket.js 

import store from '@/store'
import { Message } from 'element-ui'
var ws;
var tt;
var lockReconnect = false;//避免重复连接
var clientId = localStorage.getItem("clientId")//缓存中取出客户端id

var websocket = {
    Init: function (url, clientId) {
        if ("WebSocket" in window) {
            ws = new WebSocket(url + clientId);
        } else if ("MozWebSocket" in window) {
            ws = new MozWebSocket(url + clientId);
        } else {
            console.log("您的浏览器不支持 WebSocket!");
            return;
        }

        ws.onmessage = function (e) {
            console.log("接收消息:" + e.data)
            heartCheck.start()
            if (e.data == 'ok') {//心跳消息不做处理
                return
            }
            //messageHandle(e.data)
        }

        ws.onclose = function () {
            console.log("连接已关闭")
            Message({
                message: '连接已关闭',
                type: 'error',
            });
            reconnect(clientId);
        }

        ws.onopen = function () {
            console.log("连接成功")
            Message({
                message: '连接成功',
                type: 'success',
            });
            heartCheck.start();
        }

        ws.onerror = function (e) {
            console.log("数据传输发生错误");
            Message({
                message: '数据传输发生错误',
                type: 'error',
            });
            reconnect(clientId)
        }
    },
    Send: function (sender, reception, body, flag) {
        let data = {
            sender: sender,
            reception: reception,
            body: body,
            flag: flag
        }
        let msg = JSON.stringify(data)
        console.log("发送消息:" + msg)
        ws.send(msg)
    },
    getWebSocket() {
        return ws;
    },
    getStatus() {
        if (ws.readyState == 0) {
            return "未连接";
        } else if (ws.readyState == 1) {
            return "已连接";
        } else if (ws.readyState == 2) {
            return "连接正在关闭";
        } else if (ws.readyState == 3) {
            return "连接已关闭";
        }
    }
}

export default websocket;

//根据消息标识做不同的处理
function messageHandle(message) {
    let msg = JSON.parse(message)
    switch (msg.flag) {
        case 'command':
            console.log("指令消息类型")
            break;
        case 'inform':
            console.log("通知")
            break;
        default:
            console.log("未知消息类型")
    }
}

function reconnect(sname) {
    if (lockReconnect) {
        return;
    };
    lockReconnect = true;
    //没连接上会一直重连,设置延迟避免请求过多
    tt && clearTimeout(tt);
    tt = setTimeout(function () {
        console.log("执行断线重连...")
        websocket.Init(sname);
        lockReconnect = false;
    }, 4000);
}

//心跳检测
var heartCheck = {
    timeout: 1000 * 60 * 3,
    timeoutObj: null,
    serverTimeoutObj: null,
    start: function () {
        console.log('开始心跳检测');
        var self = this;
        this.timeoutObj && clearTimeout(this.timeoutObj);
        this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
        this.timeoutObj = setTimeout(function () {
            //这里发送一个心跳,后端收到后,返回一个心跳消息,
            //onmessage拿到返回的心跳就说明连接正常
            console.log('心跳检测...');
            ws.send("HeartBeat:" + clientId);
            self.serverTimeoutObj = setTimeout(function () {
                if (ws.readyState != 1) {
                    ws.close();
                }
                // createWebSocket();
            }, self.timeout);

        }, this.timeout)
    }
}

使用方法

直接在生命周期里调用这个方法就可以,如果想在全局调用就在app.vue中使用

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
import websocket from '@/js/websocket'
export default {
  name: 'App',
  created(){
	  localStorage.setItem("clientId","user-1")
	  websocket.Init("url地址","user-1")
  }
}
</script>

在uniapp中使用

websocket.js

let isSocketClose=false;    // 是否关闭socket
let reconnectCount=5;    // 重连次数
let heartbeatInterval="";   // 心跳定时器
let socketTask = null;  // websocket对象

let  againTimer = null;//断线重连定时器


let url = null;
let onReFn = null;
let onSucFn = null;
let onErrFn = null;

/**
 * sockeUrl:websocet的地址
 * onReceive:消息监听的回调
 * onErrorEvent:抛出错误的回调,且弹窗连接失败的提示框
 * onErrorSucceed:抛出成功回调,主要用于隐藏连接失败的提示框
 * */
const sokcet= (sockeUrl,onReceive,onErrorEvent,onErrorSucceed)=> {
               url = sockeUrl;
               onReFn= onReceive;
               onErrFn= onErrorEvent;
               onSucFn= onErrorSucceed;
               isSocketClose=false; 
              //判断是否有websocet对象,有的话清空
               if(socketTask){
                   socketTask.close();
                   socketTask = null;
                   clearInterval(heartbeatInterval);
               }
    
               //WebSocket的地址
                // 【非常重要】必须确保你的服务器是成功的,如果是手机测试千万别使用ws://127.0.0.1:9099【特别容易犯的错误】
                let url = sockeUrl
                // 连接
            socketTask = uni.connectSocket({
                    url: url,
                    success(data) {
                                console.log("websocket连接成功");
                                clearInterval(againTimer)//断线重连定时器
                            },
                    fail: (err) => {
                        console.log("报错",err);
                    }
                });
                
                // 连接打开
                socketTask.onOpen((res)=>{
                    console.log('WebSocket打开');
                    clearInterval(againTimer)//断线重连定时器
                     onErrorSucceed({isShow:false}) // 用于提示框的隐藏
                    heartbeatInterval && clearInterval(heartbeatInterval);
                    // 10秒发送一次心跳
                    heartbeatInterval = setInterval(() => {
                        sendMsg('心跳ing')
                    }, 1000*5)
                })
                 // 监听连接失败
                socketTask.onError((err)=>{
                    console.log('WebSocket连接打开失败,请检查',err);
                    //停止发送心跳
                    clearInterval(heartbeatInterval)
                    //如果不是人为关闭的话,进行重连
                    if (!isSocketClose) { 
                        reconnect(url,onErrorEvent)
                    }
                })
             
                // // 监听连接关闭 -
                socketTask.onClose((e) => {
                            console.log('WebSocket连接关闭!');
                            clearInterval(heartbeatInterval)
                            if (!isSocketClose) {
                                reconnect(url,onErrorEvent)
                            }
                    })

                // 监听收到信息
                socketTask.onMessage((res) => {
                        uni.hideLoading()
                        console.log(res,'res监听收到信息')
                        let serverData = res.data
                        //与后端规定好返回值分别代表什么,写业务逻辑
                          serverData && onReceive(serverData);
                });
                
            
}

    const reconnect = (url,onErrorEvent)=>{
                 console.log('进入断线重连',isSocketClose);
                     clearInterval(againTimer)//断线重连定时器
                     clearInterval(heartbeatInterval);
                     socketTask && socketTask.close(); // 确保已经关闭后再重新打开
                     socketTask = null;
                    onErrorEvent({isShow:true,messge:'扫描头服务正在连接...'})
                    // 连接  重新调用创建websocet方法
            againTimer    = setInterval(()=>{
                     sokcet(url,onReFn,onErrFn,onSucFn)
                     console.log('在重新连接中...');
                 },1000*5)
                    
                                        
        }    

  const sendMsg = (msg)=>{   //向后端发送命令
                msg = JSON.stringify(msg)
                try{
                    //通过 WebSocket 连接发送数据
                    socketTask.send({
                        data: msg
                    });
                }catch(e){
                    if(isSocketClose){
                        return
                    }else{
                        reconnect(url,onErrFn)
                    }

                }
            }
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】beforeDestroy() {websocetObj.stop();}
            
const stop = ()=>{
         isSocketClose = true
        clearInterval(heartbeatInterval);
        clearInterval(againTimer)//断线重连定时器
        socketTask.close(); // 确保已经关闭后再重新打开
        socketTask = null;
}

 

 
 
 export const websocketObj = {
     sokcet,
     stop,
    sendMsg
 };
 

使用方法

<template>
    <view class="container">
            {{ webtext }}
    </view>
</template>
<script>

import { websocketObj } from '@/utils/websocket.js';

export default {
data() {
    return {
            webtext:'',
            
      }
},
        methods: {
            //websocet函数回调:返回监听的数据
            getWebsocetData(val){
            // val = String.fromCharCode.apply(null, new Uint8Array(val)).trim()  如果后端返回数据格式是其他的,可能需要转换一下,比如这个,应该是转Unicode编码
                console.log(val,'函数回调');
                this.scanCode = val;
            },
            //websocet函数抛错: 返回错误信息 用于用户提示
            getWebsocetError(err){
                this.webtext = err.messge;
                console.log('websocet函数抛错');
            },
            //websocet函数成功进入: 监听连接状态,在失败的时候弹窗提示,具体需求看自身情况
            onErrorSucceed(val){
                console.log('websocet函数成功进入');
            }   
        },
        mounted() {
        },
        onLoad() {
        // 在onload的时候调用,创建webscoet连接对象,参数分别为:url、获取后端返回数据、监听websocket的链接失败返回的报错、监听链接状态,返回布尔值
            websocketObj.sokcet('ws://192.168.xxxx',this.getWebsocetData,this.getWebsocetError,this.onErrorSucceed)
        
    },
    //离开页面销毁websocket
        beforeDestroy() {
            websocketObj.stop();
       },
    }
</script>

相关推荐

  1. vueuniapp使用 websocket封装js

    2024-06-14 18:22:03       34 阅读
  2. vue项目封装使用WebSocket(2)

    2024-06-14 18:22:03       45 阅读
  3. 如何uniapp使用websocket

    2024-06-14 18:22:03       20 阅读
  4. vue项目webSocket封装(传token)

    2024-06-14 18:22:03       58 阅读
  5. Vue项目WebSocket封装

    2024-06-14 18:22:03       60 阅读
  6. Vue使用websocket的流程

    2024-06-14 18:22:03       28 阅读

最近更新

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

    2024-06-14 18:22:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-14 18:22:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-06-14 18:22:03       82 阅读
  4. Python语言-面向对象

    2024-06-14 18:22:03       91 阅读

热门阅读

  1. Linux 常用命令合集

    2024-06-14 18:22:03       26 阅读
  2. React的@reduxjs/toolkit的异步方法处理和实现

    2024-06-14 18:22:03       27 阅读
  3. 【Go】使用Go语言实现AES CBC No Padding加密和解密

    2024-06-14 18:22:03       32 阅读
  4. Redis缓存(笔记三:Redis6新数据类型)

    2024-06-14 18:22:03       27 阅读
  5. junit mockito Dao层

    2024-06-14 18:22:03       32 阅读
  6. 如何对Spring管理bean进行增强

    2024-06-14 18:22:03       36 阅读
  7. cloud compare编译

    2024-06-14 18:22:03       25 阅读
  8. Django Form 组件

    2024-06-14 18:22:03       33 阅读
  9. Scala 入门指南:从零开始的大数据开发

    2024-06-14 18:22:03       30 阅读
  10. Scala入门教程

    2024-06-14 18:22:03       34 阅读
  11. 深度学习 - RNN训练过程推演

    2024-06-14 18:22:03       22 阅读