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 相关文章推荐
js 用CreateElement动态创建标签示例
Nov 20 Javascript
jquery根据属性和index来查找属性值并操作
Jul 25 Javascript
jQuery实现默认是闭合的FAQ展开效果菜单
Sep 14 Javascript
JQuery+Ajax实现数据查询、排序和分页功能
Sep 27 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
Jan 12 Javascript
JS制作图形验证码实现代码
Oct 19 Javascript
基于vue-cli配置lib-flexible + rem实现移动端自适应
Dec 26 Javascript
vue的传参方式汇总和router使用技巧
May 22 Javascript
一秒学会微信小程序制作table表格
Feb 14 Javascript
React-redux实现小案例(todolist)的过程
Sep 29 Javascript
vue3.0 上手体验
Sep 21 Javascript
React forwardRef的使用方法及注意点
Jun 13 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 抓取网页图片并且另存为的实现代码
2010/03/24 PHP
php面向对象中static静态属性和静态方法的调用
2015/02/08 PHP
Zend Framework实现自定义过滤器的方法
2016/12/09 PHP
微信公众平台开发教程③ PHP实现微信公众号支付功能图文详解
2019/04/10 PHP
php和asp语法上的区别总结
2019/05/12 PHP
php array_chunk()函数用法与注意事项
2019/07/12 PHP
JavaScript进阶教程(第四课第一部分)
2007/04/05 Javascript
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
浅谈javascript构造函数与实例化对象
2015/06/22 Javascript
js控制多图左右滚动切换效果代码分享
2015/08/26 Javascript
通过jquery-ui中的sortable来实现拖拽排序的简单实例
2016/05/24 Javascript
JavaScript Ajax编程 应用篇
2016/07/02 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
JS设置手机验证码60s等待实现代码
2017/06/14 Javascript
原生JS写Ajax的请求函数功能
2017/12/22 Javascript
vue2 全局变量的设置方法
2018/03/09 Javascript
js传递数组参数到后台controller的方法
2018/03/29 Javascript
使用 JavaScript 创建并下载文件(模拟点击)
2019/10/25 Javascript
Vue替代marquee标签超出宽度文字横向滚动效果
2019/12/09 Javascript
Vue+penlayers实现多边形绘制及展示
2020/12/24 Vue.js
Vue ​v-model相关知识总结
2021/01/28 Vue.js
python实现网页链接提取的方法分享
2014/02/25 Python
在Mac OS上使用mod_wsgi连接Python与Apache服务器
2015/12/24 Python
在cmder下安装ipython以及环境的搭建
2018/10/19 Python
opencv 获取rtsp流媒体视频的实现方法
2019/08/23 Python
Python经纬度坐标转换为距离及角度的实现
2020/11/01 Python
详解pycharm连接远程linux服务器的虚拟环境的方法
2020/11/13 Python
css3 中的新特性加强记忆详解
2016/04/16 HTML / CSS
阿联酋最好的手机、电子产品和家用电器网上商店:Eros Digital Home
2020/08/09 全球购物
澳大利亚在线批发商:Simply Wholesale
2021/02/24 全球购物
Tomcat的缺省是多少,怎么修改
2014/04/09 面试题
企业消防安全责任书
2014/07/23 职场文书
中层领导干部群众路线对照检查材料思想汇报
2014/10/02 职场文书
趵突泉导游词
2015/02/03 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
Golang二维切片初始化的实现
2021/04/08 Golang