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


Posted in Javascript onDecember 09, 2019

公司做了个数字货币行情的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发送消息并实时接收消息,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JavaScript中的prototype使用说明
Apr 13 Javascript
JavaScript eval() 函数介绍及应用示例
Jul 29 Javascript
node.js中的console.timeEnd方法使用说明
Dec 09 Javascript
Node.js中使用socket创建私聊和公聊聊天室
Nov 19 Javascript
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
Dec 07 Javascript
js中window.open的参数及注意注意事项
Jul 06 Javascript
微信小程序实现添加手机联系人功能示例
Nov 30 Javascript
security.js实现的RSA加密功能示例
Jun 06 Javascript
angularJs中orderBy筛选以及filter过滤数据的方法
Sep 30 Javascript
微信小程序公用参数与公用方法用法示例
Jan 09 Javascript
Vue2.x通用条件搜索组件的封装及应用详解
May 28 Javascript
让Vue响应Map或Set的变化操作
Nov 11 Javascript
Vue extend的基本用法(实例详解)
Dec 09 #Javascript
vue基于v-charts封装双向条形图的实现代码
Dec 09 #Javascript
微信小程序图片加载失败时替换为默认图片的方法
Dec 09 #Javascript
vue如何使用async、await实现同步请求
Dec 09 #Javascript
Vue替代marquee标签超出宽度文字横向滚动效果
Dec 09 #Javascript
vue新建项目并配置标准路由过程解析
Dec 09 #Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
Dec 09 #Javascript
You might like
php上传、管理照片示例
2006/10/09 PHP
使用PHP求两个文件的相对路径
2013/06/20 PHP
简单的php文件上传(实例)
2013/10/27 PHP
php实现跨域提交form表单的方法【2种方法】
2016/10/17 PHP
Laravel 实现密码重置功能
2018/02/23 PHP
PHP实现微信退款功能
2018/10/02 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
JQuery的ajax基础上的超强GridView展示
2009/09/18 Javascript
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
jQuery 拖动层(在可视区域范围内)
2012/05/24 Javascript
JavaScript 用Node.js写Shell脚本[译]
2012/09/20 Javascript
JavaScript获取和设置CheckBox状态的简单方法
2013/07/05 Javascript
javascript记录文本框内文字个数检测文字个数变化
2014/10/14 Javascript
JS实现图片上传预览功能
2016/11/21 Javascript
深入浅析Vue不同场景下组件间的数据交流
2017/08/15 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
手把手带你封装一个vue component第三方库
2019/02/14 Javascript
微信小程序Echarts图表组件使用方法详解
2019/06/25 Javascript
TypeScript中使用getElementXXX()的示例代码
2019/09/12 Javascript
js实现的在本地预览图片功能示例
2019/11/09 Javascript
封装Vue Element的table表格组件的示例详解
2020/08/19 Javascript
mustache.js实现首页元件动态渲染的示例代码
2020/12/28 Javascript
[02:28]DOTA2 2015国际邀请赛中国区预选赛首日现场百态
2015/05/26 DOTA
python实现的一个火车票转让信息采集器
2014/07/09 Python
使用Python实现下载网易云音乐的高清MV
2015/03/16 Python
python实现读取命令行参数的方法
2015/05/22 Python
tensorflow训练中出现nan问题的解决
2018/02/10 Python
Python音频操作工具PyAudio上手教程详解
2019/06/26 Python
如何用Python来理一理红楼梦里的那些关系
2019/08/14 Python
Python warning警告出现的原因及忽略方法
2020/01/31 Python
查看keras各种网络结构各层的名字方式
2020/06/11 Python
基于Python爬取素材网站音频文件
2020/10/21 Python
Eclipse面试题
2014/03/22 面试题
生产班组长岗位职责
2014/01/05 职场文书
关于廉洁的广播稿
2014/01/30 职场文书
单位未婚证明范本
2014/11/25 职场文书