当前位置: 移动技术网 > IT编程>开发语言>JavaScript > vue 实现websocket发送消息并实时接收消息

vue 实现websocket发送消息并实时接收消息

2020年03月09日  | 移动技术网IT编程  | 我要评论

公司做了个数字货币行情的h5,需要用到websocket,刚好自己也不会,可以学习一下,美滋滋。

项目结合vue脚手架和websocket来搭建,主要遇到了两个问题,一个是:断开重连机制要如何处理;另外一个是:如何在页面上随时的发送消息并实时接收返回的数据,断开重连后又如何重新发送消息,接收消息

一、断开重连机制处理 (

写一个重连的方法(重连方法中必须加一把锁,重连方法执行过程中不再执行重连动作,避免重复连接),然后在websocket的onclose和error中绑定重连方法,这样一般情况下,websocket断开或者链接出错就可以实现重连了。针对断网重连问题,就需要用心跳检测了(主要是利用websocket定时发送消息,当超过一定时间消息还未发送成功,浏览器的websocket会自动触发onclose方法,而此时onclose有绑定了重连函数,于是就触发websocket重新连接),项目这边暂时不考虑这个,所以没做心跳检测。

主要代码:

let socket = null;
let lockreconnet = false; //避免重复连接
const wsurl = '自己的websocket接口';
let createsocket = url=>{ //创建socket
 try{
 if('websocket' in window){
 socket = new websocket(url)
 }else if('mozwebsocket' in window){
 socket = new mozwebsocket(url)
 }
 initsocket()
 }catch(e){
 reconnet(url)
 }
}
let initsocket = ()=>{ //初始化websocket
 socket.onopen = ()=>{
 console.log('socket连接成功')
 //heartcheck.reset().start() //后端说暂时不需要做心跳检测
 
 }
 
 socket.onmessage = (ev)=>{
 console.log(ev,'连接正常')
 //heartcheck.reset().start() //后端说暂时不需要做心跳检测
 }
 
 socket.onerror = ()=>{
 console.log('websocket服务出错了---onerror');
 reconnet(wsurl) 
 }
 
 socket.onclose = ()=>{
 console.log('websocket服务关闭了+++onclose');
 reconnet(wsurl)
 }
}
let reconnet = url=>{ //重新连接websock函数
 if(lockreconnet)
 return false
 lockreconnet = true
 settimeout(()=>{
 createsocket(url)
 lockreconnet = false
 },2000)
}
let heartcheck = { //心跳检测
 timeout: 60*1000,
 timeoutobj: null,
 servertimeoutobj: null,
 reset(){
 cleartimeout(this.timeoutobj)
 cleartimeout(this.servertimeoutobj)
 return this;
 },
 start(){
 let that = this;
 this.timeoutobj = settimeout(()=>{
 //发送数据,如果onmessage能接收到数据,表示连接正常,然后在onmessage里面执行reset方法清除定时器
 socket.send('heart check')
 this.servertimeoutobj = settimeout(()=>{
 socket.close()
 },that.timeout)
 },this.timeout)
 }
}

二、在页面上随时发送消息并实时接收消息

在上面代码的基础上增加一个发送数据的方法,该方法有两个参数,一个是需要发送的数据;另一个为接收和处理返回数据的回调函数,然后把这个方法暴露出去并挂载到vue原型上,这样就可以在任意页面或者组件随时的发送消息,并接收消息了。具体代码:

let sendmsg = (data,callback)=>{ //发送数据,接收处理数据
 if(socket.readystate===1){
 globalcallback = callback; //把接收处理回调函数保存到全局
 senddata = data; //把发送数据也保存到全局
 
 data = json.stringify(data);
 socket.send(data);
 }else{
 settimeout(()=>{
 console.log(socket,'等待socket链接成功')
 sendmsg(data,callback)
 },1500)
 return false
 }
 socket.onmessage = ev=>{ //重新监听onmessage,并把数据传给回调函数
 callback && callback(ev)
 }
}

三、断开重连后如何重新发送消息和接收消息

增加一个保存要发送消息的全局变量,以及一个保存接收处理消息回调函数的全局变量,当重连触发后,重新调用下senmsg方法,并把这两个变量传进去就可以了。

完整的封装代码(mysocket.js):

//import vue from 'vue'
let socket = null;
let lockreconnet = false; //避免重复连接
const wsurl = '自己的websocket接口';
let isreconnet = false;
let globalcallback = null,senddata = null; //把要发送给socket的数据和处理socket返回数据的回调保存起来
let createsocket = url=>{ //创建socket
 try{
 if('websocket' in window){
 socket = new websocket(url)
 }else if('mozwebsocket' in window){
 socket = new mozwebsocket(url)
 }
 //vue.prototype.socket = socket //需要主动关闭的话就可以直接调用this.socket.close()进行关闭,不需要的话这个可以去掉
 initsocket()
 }catch(e){
 reconnet(url)
 }
}
let sendmsg = (data,callback)=>{ //发送数据,接收数据
 if(socket.readystate===1){
 globalcallback = callback;
 senddata = data;
 
 data = json.stringify(data);
 socket.send(data);
 }else{
 settimeout(()=>{
 console.log(socket,'等待socket链接成功')
 sendmsg(data,callback)
 },1500)
 return false
 }
 socket.onmessage = ev=>{
 callback && callback(ev)
 }
}
let initsocket = ()=>{ //初始化websocket
 socket.onopen = ()=>{
 console.log('socket连接成功')
 //heartcheck.reset().start() //后端说暂时不需要做心跳检测
 
 if(isreconnet){//执行全局回调函数
 //console.log('websocket重新连接了')
 sendmsg(senddata,globalcallback)
 isreconnet = false
 }
 }
 
 socket.onmessage = (ev)=>{
 console.log(ev,'连接正常')
 //heartcheck.reset().start() //后端说暂时不需要做心跳检测
 }
 
 socket.onerror = ()=>{
 console.log('websocket服务出错了---onerror');
 reconnet(wsurl) 
 }
 
 socket.onclose = ()=>{
 console.log('websocket服务关闭了+++onclose');
 reconnet(wsurl)
 }
}
let reconnet = url=>{ //重新连接websock函数
 if(lockreconnet)
 return false
 
 isreconnet = true;
 lockreconnet = true
 settimeout(()=>{
 createsocket(url)
 lockreconnet = false
 },2000)
}
let heartcheck = { //心跳检测
 timeout: 60*1000,
 timeoutobj: null,
 servertimeoutobj: null,
 reset(){
 cleartimeout(this.timeoutobj)
 cleartimeout(this.servertimeoutobj)
 return this;
 },
 start(){
 let that = this;
 this.timeoutobj = settimeout(()=>{
 //发送数据,如果onmessage能接收到数据,表示连接正常,然后在onmessage里面执行reset方法清除定时器
 socket.send('heart check')
 this.servertimeoutobj = settimeout(()=>{
 socket.close()
 },that.timeout)
 },this.timeout)
 }
}
createsocket(wsurl)
export default {sendmsg}

在main.js里面引入这个文件,并把sendmsg挂载到vue原型上,就可以再页面上随时发送消息接收消息了。

import socket from './assets/js/mysocket'
vue.prototype.sendmsg = socket.sendmsg

在页面上调用方法:

getsocketdata(symbol){
 let data = {"event":"subscription","data":"market.kline."+symbol};
 this.sendmsg(data,ev=>{
 console.log(json.parse(ev.data),'k线相关数据')
 })
 }

效果: 

总结

以上所述是小编给大家介绍的vue 实现websocket发送消息并实时接收消息,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网