vue 實(shí)現(xiàn)websocket發(fā)送消息并實(shí)時(shí)接收消息
公司做了個(gè)數(shù)字貨幣行情的H5,需要用到websocket,剛好自己也不會(huì),可以學(xué)習(xí)一下,美滋滋。
項(xiàng)目結(jié)合vue腳手架和websocket來搭建,主要遇到了兩個(gè)問題,一個(gè)是:斷開重連機(jī)制要如何處理;另外一個(gè)是:如何在頁面上隨時(shí)的發(fā)送消息并實(shí)時(shí)接收返回的數(shù)據(jù),斷開重連后又如何重新發(fā)送消息,接收消息
一、斷開重連機(jī)制處理 (詳細(xì)參考這里)
寫一個(gè)重連的方法(重連方法中必須加一把鎖,重連方法執(zhí)行過程中不再執(zhí)行重連動(dòng)作,避免重復(fù)連接),然后在websocket的onclose和error中綁定重連方法,這樣一般情況下,websocket斷開或者鏈接出錯(cuò)就可以實(shí)現(xiàn)重連了。針對(duì)斷網(wǎng)重連問題,就需要用心跳檢測(cè)了(主要是利用websocket定時(shí)發(fā)送消息,當(dāng)超過一定時(shí)間消息還未發(fā)送成功,瀏覽器的websocket會(huì)自動(dòng)觸發(fā)onclose方法,而此時(shí)onclose有綁定了重連函數(shù),于是就觸發(fā)websocket重新連接),項(xiàng)目這邊暫時(shí)不考慮這個(gè),所以沒做心跳檢測(cè)。
主要代碼:
let socket = null;
let lockReconnet = false; //避免重復(fù)連接
const wsUrl = '自己的websocket接口';
let createSocket = url=>{ //創(chuàng)建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() //后端說暫時(shí)不需要做心跳檢測(cè)
}
socket.onmessage = (ev)=>{
console.log(ev,'連接正常')
//heartCheck.reset().start() //后端說暫時(shí)不需要做心跳檢測(cè)
}
socket.onerror = ()=>{
console.log('websocket服務(wù)出錯(cuò)了---onerror');
reconnet(wsUrl)
}
socket.onclose = ()=>{
console.log('websocket服務(wù)關(guān)閉了+++onclose');
reconnet(wsUrl)
}
}
let reconnet = url=>{ //重新連接websock函數(shù)
if(lockReconnet)
return false
lockReconnet = true
setTimeout(()=>{
createSocket(url)
lockReconnet = false
},2000)
}
let heartCheck = { //心跳檢測(cè)
timeout: 60*1000,
timeoutObj: null,
serverTimeoutObj: null,
reset(){
clearTimeout(this.timeoutObj)
clearTimeout(this.serverTimeoutObj)
return this;
},
start(){
let that = this;
this.timeoutObj = setTimeout(()=>{
//發(fā)送數(shù)據(jù),如果onmessage能接收到數(shù)據(jù),表示連接正常,然后在onmessage里面執(zhí)行reset方法清除定時(shí)器
socket.send('heart check')
this.serverTimeoutObj = setTimeout(()=>{
socket.close()
},that.timeout)
},this.timeout)
}
}
二、在頁面上隨時(shí)發(fā)送消息并實(shí)時(shí)接收消息
在上面代碼的基礎(chǔ)上增加一個(gè)發(fā)送數(shù)據(jù)的方法,該方法有兩個(gè)參數(shù),一個(gè)是需要發(fā)送的數(shù)據(jù);另一個(gè)為接收和處理返回?cái)?shù)據(jù)的回調(diào)函數(shù),然后把這個(gè)方法暴露出去并掛載到Vue原型上,這樣就可以在任意頁面或者組件隨時(shí)的發(fā)送消息,并接收消息了。具體代碼:
let sendMsg = (data,callback)=>{ //發(fā)送數(shù)據(jù),接收處理數(shù)據(jù)
if(socket.readyState===1){
globalCallback = callback; //把接收處理回調(diào)函數(shù)保存到全局
sendData = data; //把發(fā)送數(shù)據(jù)也保存到全局
data = JSON.stringify(data);
socket.send(data);
}else{
setTimeout(()=>{
console.log(socket,'等待socket鏈接成功')
sendMsg(data,callback)
},1500)
return false
}
socket.onmessage = ev=>{ //重新監(jiān)聽onmessage,并把數(shù)據(jù)傳給回調(diào)函數(shù)
callback && callback(ev)
}
}
三、斷開重連后如何重新發(fā)送消息和接收消息
增加一個(gè)保存要發(fā)送消息的全局變量,以及一個(gè)保存接收處理消息回調(diào)函數(shù)的全局變量,當(dāng)重連觸發(fā)后,重新調(diào)用下senMsg方法,并把這兩個(gè)變量傳進(jìn)去就可以了。
完整的封裝代碼(mysocket.js):
//import Vue from 'vue'
let socket = null;
let lockReconnet = false; //避免重復(fù)連接
const wsUrl = '自己的websocket接口';
let isReconnet = false;
let globalCallback = null,sendData = null; //把要發(fā)送給socket的數(shù)據(jù)和處理socket返回?cái)?shù)據(jù)的回調(diào)保存起來
let createSocket = url=>{ //創(chuàng)建socket
try{
if('WebSocket' in window){
socket = new WebSocket(url)
}else if('MozWebSocket' in window){
socket = new MozWebSocket(url)
}
//Vue.prototype.socket = socket //需要主動(dòng)關(guān)閉的話就可以直接調(diào)用this.socket.close()進(jìn)行關(guān)閉,不需要的話這個(gè)可以去掉
initSocket()
}catch(e){
reconnet(url)
}
}
let sendMsg = (data,callback)=>{ //發(fā)送數(shù)據(jù),接收數(shù)據(jù)
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() //后端說暫時(shí)不需要做心跳檢測(cè)
if(isReconnet){//執(zhí)行全局回調(diào)函數(shù)
//console.log('websocket重新連接了')
sendMsg(sendData,globalCallback)
isReconnet = false
}
}
socket.onmessage = (ev)=>{
console.log(ev,'連接正常')
//heartCheck.reset().start() //后端說暫時(shí)不需要做心跳檢測(cè)
}
socket.onerror = ()=>{
console.log('websocket服務(wù)出錯(cuò)了---onerror');
reconnet(wsUrl)
}
socket.onclose = ()=>{
console.log('websocket服務(wù)關(guān)閉了+++onclose');
reconnet(wsUrl)
}
}
let reconnet = url=>{ //重新連接websock函數(shù)
if(lockReconnet)
return false
isReconnet = true;
lockReconnet = true
setTimeout(()=>{
createSocket(url)
lockReconnet = false
},2000)
}
let heartCheck = { //心跳檢測(cè)
timeout: 60*1000,
timeoutObj: null,
serverTimeoutObj: null,
reset(){
clearTimeout(this.timeoutObj)
clearTimeout(this.serverTimeoutObj)
return this;
},
start(){
let that = this;
this.timeoutObj = setTimeout(()=>{
//發(fā)送數(shù)據(jù),如果onmessage能接收到數(shù)據(jù),表示連接正常,然后在onmessage里面執(zhí)行reset方法清除定時(shí)器
socket.send('heart check')
this.serverTimeoutObj = setTimeout(()=>{
socket.close()
},that.timeout)
},this.timeout)
}
}
createSocket(wsUrl)
export default {sendMsg}
在main.js里面引入這個(gè)文件,并把sendMsg掛載到Vue原型上,就可以再頁面上隨時(shí)發(fā)送消息接收消息了。
import socket from './assets/js/mysocket' Vue.prototype.sendMsg = socket.sendMsg
在頁面上調(diào)用方法:
getSocketData(symbol){
let data = {"event":"subscription","data":"market.kline."+symbol};
this.sendMsg(data,ev=>{
console.log(JSON.parse(ev.data),'K線相關(guān)數(shù)據(jù)')
})
}
效果:

總結(jié)
以上所述是小編給大家介紹的vue 實(shí)現(xiàn)websocket發(fā)送消息并實(shí)時(shí)接收消息,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
vue實(shí)現(xiàn)微信公眾號(hào)h5跳轉(zhuǎn)小程序的示例代碼
本文主要介紹了vue實(shí)現(xiàn)微信公眾號(hào)h5跳轉(zhuǎn)小程序的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
基于Vue2x實(shí)現(xiàn)響應(yīng)式自適應(yīng)輪播組件插件VueSliderShow功能
本文講述的是從開發(fā)一款基于Vue2x的響應(yīng)式自適應(yīng)輪播組件插件的一個(gè)全過程,包含發(fā)布到npm,構(gòu)建自己的npm包,供下載安裝使用的技巧,非常不錯(cuò),具有一定的參考借鑒價(jià)值,感興趣的朋友跟隨腳本之家小編一起看看吧2018-05-05
vue+iview框架實(shí)現(xiàn)左側(cè)動(dòng)態(tài)菜單功能的示例代碼
這篇文章主要介紹了vue+iview框架實(shí)現(xiàn)左側(cè)動(dòng)態(tài)菜單功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
淺談使用mpvue開發(fā)小程序需要注意和了解的知識(shí)點(diǎn)
這篇文章主要介紹了淺談使用mpvue開發(fā)小程序需要注意和了解的知識(shí)點(diǎn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05
vue3開啟攝像頭并進(jìn)行拍照的實(shí)現(xiàn)示例
本文主要介紹了vue3開啟攝像頭并進(jìn)行拍照的實(shí)現(xiàn)示例,主要是使用navigator.mediaDevices.getUserMedia這個(gè)API來實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
Vuex中actions優(yōu)雅處理接口請(qǐng)求的方法
在項(xiàng)目開發(fā)中,如果使用到了 vuex,通常我會(huì)將所有的接口請(qǐng)求單獨(dú)用一個(gè)文件管理,這篇文章主要介紹了Vuex中actions如何優(yōu)雅處理接口請(qǐng)求,業(yè)務(wù)邏輯寫在 actions 中,本文給大家分享完整流程需要的朋友可以參考下2022-11-11
Vue?2?如何添加?register-service-worker?實(shí)現(xiàn)緩存請(qǐng)求的問題
這篇文章主要介紹了Vue?2?如何添加?register-service-worker?以實(shí)現(xiàn)緩存請(qǐng)求的目的,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11

