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>