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 相关文章推荐
JQUERY的属性选择符和自定义选择符使用方法(二)
Apr 07 Javascript
js中将URL中的参数提取出来作为对象的实现代码
Aug 16 Javascript
javascript实现移动端上的触屏拖拽功能
Mar 04 Javascript
简单学习vue指令directive
Nov 03 Javascript
Jquery鼠标放上去显示全名的实现方法
Feb 06 Javascript
js 调用百度分享功能
Feb 27 Javascript
jquery点击回车键实现登录效果并默认焦点的方法
Mar 09 jQuery
Vue异步组件处理路由组件加载状态的解决方案
Sep 07 Javascript
javascript动态创建对象的属性详解
Nov 07 Javascript
微信小程序template模版的使用方法
Apr 13 Javascript
vue项目打包上传github并制作预览链接(pages)
Apr 19 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
Jan 12 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
解决phpmyadmin 乱码,支持gb2312和utf-8
2006/11/20 PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
2011/01/18 PHP
php mysql_real_escape_string函数用法与实例教程
2013/09/30 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
2014/07/08 PHP
php随机取mysql记录方法小结
2014/12/27 PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
2017/04/18 PHP
浅析PHP类的反射来实现依赖注入过程
2018/02/06 PHP
PHP 构造函数和析构函数原理与用法分析
2020/04/21 PHP
range 标准化之获取
2011/08/28 Javascript
jquery 实现上下滚动效果示例代码
2013/08/09 Javascript
概述一个页面从输入URL到页面加载完的过程
2016/12/16 Javascript
JS求解三元一次方程组值的方法
2017/01/03 Javascript
Vue.js实现表格动态增加删除的方法(附源码下载)
2017/01/20 Javascript
js实现短信发送倒计时功能(正则验证)
2017/02/10 Javascript
node通过express搭建自己的服务器
2017/09/30 Javascript
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
jquery实现点击a链接,跳转之后,该a链接处显示背景色的方法
2018/01/18 jQuery
node基于puppeteer模拟登录抓取页面的实现
2018/05/09 Javascript
浅谈react性能优化的方法
2018/09/05 Javascript
原生JS实现逼真的图片3D旋转效果详解
2019/02/16 Javascript
js canvas实现星空连线背景特效
2019/11/01 Javascript
Vue export import 导入导出的多种方式与区别介绍
2020/02/12 Javascript
Python文件及目录操作实例详解
2015/06/04 Python
对Tensorflow中的变量初始化函数详解
2018/07/27 Python
pycharm实现print输出保存到txt文件
2020/06/01 Python
Python实现中英文全文搜索的示例
2020/12/04 Python
丝芙兰美国官网:SEPHORA美国
2016/08/03 全球购物
美国创意礼品网站:UncommonGoods
2017/02/03 全球购物
Kusmi茶美国官网:优质散叶茶和茶包
2019/10/13 全球购物
秋季运动会通讯稿
2014/01/24 职场文书
数控技术专业毕业自荐书范文
2014/02/05 职场文书
差生评语大全
2014/05/04 职场文书
敬业奉献模范事迹材料
2014/12/24 职场文书
《平行四边形的面积》教学反思
2016/02/16 职场文书
MySQL中utf8mb4排序规则示例
2021/08/02 MySQL
Appium中scroll和drag_and_drop根据元素位置滑动
2022/02/15 Python