欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-04-09 16:44:39
公司做了个数字货币行情的h5,需要用到websocket,刚好自己也不会,可以学习一下,美滋滋。 项目结合vue脚手架和websocket来搭建,主要遇到了两个问题,一个是:断开重连...

公司做了个数字货币行情的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发送消息并实时接收消息

总结

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