写这篇文章主要是最近写了个移动端与PC端的通信;
写这篇文章主要是为了那些还没用过webSocket或者准备第一次用的人……毕竟我也是1年了第2次用……(笑)
下面我直接把代码贴上去,这代码也是大概几个月前写另一个项目copy来的,当时想写文章来着,结果忘了……所以这篇文章后面原文链接就么得了……
好了,下面先放代码,之后我会根据注释,简单讲一下需要注意的地方。
一.尝试连接:
const webSocketUrl = `ws://${this.serverAddress}/webSocketService/${IdCard}${isApp ? 'app' : 'pc'}`
ws:// ip地址:端口 / 接口地址 / 确保链接是唯一值(需和后端商量好,一般是id)
二.数据接收
根据不同数据做出不同的反应
三.关闭连接
可以看下面代码第一行打印,顺便找一个webSocket的code码,因为有时候webSocket莫名其妙关闭可以看code码快速锁定问题所在
四.心跳
webSocket连接是50s还是60s没反应,就会自动断开连接,所以需要保持心跳。
1.我这里设置1s,是因为java后端只是个中转站,我需要保证用户等待时间不会太久
2.当你单纯接收后端数据,可以根据需求设置时间,但不能大于50s,不然连接会断
五.销毁webSocket
设置那个变量,主要是防止因为心跳,而起死回生……
六.使用
我是mixins混入来使用的,在接口请求后,或者你需要的时间点,去创建一个webSocket就可以了
七.暂时不会用的
监听webSocket的message的传值去传输数据
最后,webSocket代码如下,是个 .js 文件:
export const webSocketByShz = {
data () {
return {
// webSocket
webSocket:null,
isWebSocket:false, // 是否连接上
webSocketTimeOut:null, // 定时器塞
webSocketMsgTimeOut:null, // 心跳定时器
isWebSocketMsg:false, // 心跳
webSocketMsg:null,
isDestroy: false,
serverAddress: '192.168.0.18:7012',
param: {
IdCard: '',
msg: '',
},
getObj: {},
}
},
methods: {
// ----------webSocket接通知----------by shz
// ---PS:vue.config.js也得整ws,部署的话nginx也得整ws,Chrome上有接ws通知,和xhr在一个地儿---
// 尝试连接
createdWebSocket(IdCard,msg,isApp = false){
// console.log('IdCard',IdCard)
try{
this.param = {
IdCard: IdCard + 'pc',
msg,
}
// const webSocketUrl = `ws://192.168.0.18:7012/webSocketService/${IdCard}${isApp ? 'app' : 'pc'}` // 本地测试版
const webSocketUrl = `ws://${this.serverAddress}/webSocketService/${IdCard}${isApp ? 'app' : 'pc'}` // 服务器版
// const webSocketUrl = `ws://127.0.0.1:9312/webSocketService/${this.adminMsg.adminId}` // 部署内网版
// console.log('webSocketUrl',webSocketUrl)
this.webSocket = new WebSocket(webSocketUrl)
this.initWebSocket()
}catch(e){
console.log('尝试连接失败')
this.reConnect()
}
},
// 断线重连
reConnect(){
if(this.isConnect){
return;
}else if(this.webSocketTimeOut){
clearTimeout(this.webSocketTimeOut)
}
// 防止断线后退回上一步,在
if(!this.isDestroy){
this.webSocketTimeOut = setTimeout(() => {
console.log('定时器5s尝试重连')
this.createdWebSocket(this.param.IdCard.slice(0,18),'PC端')
},3000)
}
},
// 初始化websocket
initWebSocket(){
// 已启动
this.isWebSocket = true;
// 挂函数
this.webSocket.onopen = this.openWebsocket;
this.webSocket.onerror = this.errorWebSocket;
this.webSocket.onmessage = this.messageWebSocket;
this.webSocket.onclose = this.closeWebSocket;
},
// 打开链接
openWebsocket(){
// 连接成功后再开始发送
// 后端会主动给我返值,我只需要定时器保持链接畅通
this.sendWebSocket()
},
// 当连接发生错误
errorWebSocket(){
console.log('连接错误')
this.isWebSocket = false;
// 断线重连
this.reConnect()
},
// 数据接收
messageWebSocket(e){
this.heartbeatWebSocket()
this.webSocketMsg = e
if(e.data != '未登录,连接失败' && e.data != 'PC端' && e.data.indexOf('消息') == -1){
// 人脸识别
if(e.data == 'success'){
this.getObj = e.data
console.log('人脸识别成功',e.data)
}
// 电子签名
else if(JSON.parse(e.data).resultImg){
this.getObj = JSON.parse(e.data)
console.log('电子签名成功',JSON.parse(e.data))
}
}
},
// 发送数据
sendWebSocket(){
console.log('我发送了',this.param.IdCard)
this.webSocket.send(JSON.stringify(this.param))
},
// 关闭连接
closeWebSocket(e){
console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
console.log('关闭连接'+e)
if(this.isPhone()){
this.$message.error('链接断开,请尝试重新扫码')
}
this.isWebSocket = false;
},
// 心跳---这次改5s,验证得短一点,因为 收到APP消息时间 = 心跳间隔时间
heartbeatWebSocket(){
// 不判断一下是否销毁的话,容易起死回生……
if(!this.isDestroy){
this.isWebSocketMsg = true;
this.isWebSocketMsg && clearTimeout(this.webSocketMsgTimeOut);
this.webSocketMsgTimeOut = setTimeout(() => {
// console.log('心跳~咚~咚~')
this.isWebSocketMsg = false;
this.sendWebSocket()
},1000)
}
},
// 判断是否为移动端
isPhone(){
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
return true
}else {
return false
}
}
},
beforeDestroy () {
console.log('你销毁了吗')
this.isDestroy = true
if(this.webSocketTimeOut){
clearTimeout(this.webSocketTimeOut)
}
if(this.webSocketMsgTimeOut){
clearTimeout(this.webSocketMsgTimeOut)
}
this.closeWebSocket
},
}