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 限制输入和粘贴(IE,firefox测试通过)
Nov 14 Javascript
关于viewport,Ext.panel和Ext.form.panel的关系
May 07 Javascript
jquery实现的超出屏幕时把固定层变为定位层的代码
Feb 23 Javascript
JavaScript 学习笔记之基础中的基础
Jan 13 Javascript
解析javascript瀑布流原理实现图片滚动加载
Mar 10 Javascript
JS获取当前使用的浏览器名字以及版本号实现方法
Aug 19 Javascript
js将table的每个td的内容自动赋值给其title属性的方法
Oct 13 Javascript
jquery 正整数数字校验正则表达式
Jan 10 Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
Feb 28 Javascript
Angular2学习教程之组件中的DOM操作详解
May 28 Javascript
JavaScript惰性载入函数实例分析
Mar 27 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
Aug 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
php面向对象的方法重载两种版本比较
2008/09/08 PHP
php把大写命名转换成下划线分割命名
2015/04/27 PHP
PHP框架自动加载类文件原理详解
2017/06/06 PHP
Thinkphp 框架基础之源码获取、环境要求与目录结构分析
2020/04/27 PHP
JS getStyle获取最终样式函数代码
2010/04/01 Javascript
AngularJS中使用HTML5手机摄像头拍照
2016/02/22 Javascript
javascript日期比较方法实例分析
2016/06/17 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
Bootstrap基本组件学习笔记之进度条(15)
2016/12/08 Javascript
关于Vue Webpack2单元测试示例详解
2017/08/14 Javascript
JS实现颜色的10进制转化成rgba格式的方法
2017/09/04 Javascript
使用iView Upload 组件实现手动上传图片的示例代码
2018/10/01 Javascript
vue element-ui之怎么封装一个自己的组件的详解
2019/05/20 Javascript
Vue+Element实现表格编辑、删除、以及新增行的最优方法
2019/05/28 Javascript
js瀑布流布局的实现
2020/06/28 Javascript
[57:16]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第二场
2014/05/26 DOTA
[00:11]战神迅矛
2019/03/06 DOTA
python中MySQLdb模块用法实例
2014/11/10 Python
讲解Python中for循环下的索引变量的作用域
2015/04/15 Python
Python中list初始化方法示例
2016/09/18 Python
Python实现的插入排序算法原理与用法实例分析
2017/11/22 Python
Python3单行定义多个变量或赋值方法
2018/07/12 Python
Python中的支持向量机SVM的使用(附实例代码)
2019/06/26 Python
Django中create和save方法的不同
2019/08/13 Python
python GUI库图形界面开发之PyQt5状态栏控件QStatusBar详细使用方法实例
2020/02/28 Python
mac在matplotlib中显示中文的操作方法
2020/03/06 Python
python中安装django模块的方法
2020/03/12 Python
jupyter 实现notebook中显示完整的行和列
2020/04/09 Python
HTML5 SEO优化的一些建议
2020/08/27 HTML / CSS
办公室年终个人自我评价
2013/10/28 职场文书
公司委托书格式
2014/08/01 职场文书
交通工程专业推荐信
2014/09/06 职场文书
个人党性分析材料
2014/12/19 职场文书
催款律师函范文
2015/05/27 职场文书
2015年民兵整组工作总结
2015/07/24 职场文书
十二月早安励志心语大全
2019/12/03 职场文书