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 相关文章推荐
asp javascript 实现关闭窗口时保存数据的办法
Nov 24 Javascript
javascript得到XML某节点的子节点个数的脚本
Oct 11 Javascript
jQuery EasyUI API 中文文档 - ComboBox组合框
Oct 07 Javascript
jQuery对Select的操作大集合(收藏)
Dec 28 Javascript
JQuery限制复选框checkbox可选中个数的方法
Apr 20 Javascript
使用jQuery在移动页面上添加按钮和给按钮添加图标
Dec 04 Javascript
JS实现页面数据无限加载
Sep 13 Javascript
用iframe实现不刷新整个页面上传图片的实例
Nov 18 Javascript
解决Angular.Js与Django标签冲突的方案
Dec 20 Javascript
简单的网页广告特效实例
Aug 19 Javascript
微信小程序日历弹窗选择器代码实例
May 09 Javascript
从零开始用webpack构建一个vue3.0项目工程的实现
Sep 24 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
2020显卡排行榜天梯图 显卡天梯图2020年3月最新版
2020/04/02 数码科技
php 什么是PEAR?(第二篇)
2009/03/19 PHP
DedeCMS 核心类TypeLink.class.php摘要笔记
2010/04/07 PHP
PHP设计模式之装饰者模式
2012/02/29 PHP
鼠标经过的文本框textbox变色
2009/05/21 Javascript
基于jQuery判断两个元素是否有重叠部分的代码
2012/07/25 Javascript
cookie 最近浏览记录(中文escape转码)具体实现
2013/06/08 Javascript
NodeJS url验证(url-valid)的使用方法
2013/11/18 NodeJs
NodeJS学习笔记之FS文件模块
2015/01/13 NodeJs
JQuery基础语法小结
2015/02/27 Javascript
使用js复制链接中的部分文字的方法
2015/07/30 Javascript
jquery操作checkbox火狐下第二次无法勾选的解决方法
2016/10/10 Javascript
jQuery实现的弹幕效果完整实例
2017/09/06 jQuery
Servlet3.0与纯javascript通过Ajax交互的实例详解
2018/03/18 Javascript
如何优雅的在一台vps(云主机)上面部署vue+mongodb+express项目
2019/01/20 Javascript
JavaScript实现指定数量的并发限制的示例代码
2020/03/10 Javascript
js实现轮播图特效
2020/05/28 Javascript
使用node-media-server搭建一个简易的流媒体服务器
2021/01/20 Javascript
[01:23:35]Ti4主赛事胜者组 DK vs EG 1
2014/07/19 DOTA
Python性能优化技巧
2015/03/09 Python
Python实现带参数与不带参数的多重继承示例
2018/01/30 Python
Python面向对象之反射/自省机制实例分析
2018/08/24 Python
PyCharm 2019.3发布增加了新功能一览
2019/12/08 Python
Pytorch 实现冻结指定卷积层的参数
2020/01/06 Python
使用Puppeteer爬取微信文章的实现
2020/02/11 Python
python matplotlib模块基本图形绘制方法小结【直线,曲线,直方图,饼图等】
2020/04/26 Python
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
幼儿园小班教学反思
2014/02/02 职场文书
工地安全质量标语
2014/06/07 职场文书
初中生散播谣言检讨书
2014/11/17 职场文书
2015年元旦文艺晚会总结(学院)
2014/11/28 职场文书
大足石刻导游词
2015/02/02 职场文书
经济纠纷起诉状
2015/05/20 职场文书
HTML5简单实现添加背景音乐的几种方法
2021/05/12 HTML / CSS
用Python爬取各大高校并可视化帮弟弟选大学,弟弟直呼牛X
2021/06/11 Python
Kubernetes中Deployment的升级与回滚
2022/04/01 Servers