您好,登錄后才能下訂單哦!
這篇文章主要講解了“websocket在vue2中如何封裝使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“websocket在vue2中如何封裝使用”吧!
先說需求: 頁面中有websocket連接,進(jìn)入的時(shí)候發(fā)送參數(shù)到后端,后端發(fā)送消息, 離開頁面時(shí)發(fā)送參數(shù)至后端,后端停止發(fā)送消息,不得斷開連接, 下一次進(jìn)入時(shí)頁面時(shí)不用再次連接。
因?yàn)槭侨诌B接一個(gè)websocket,所以這里采用單例模式
也是因?yàn)榉庋b的原因,頁面中肯定是直接拿不到onmessage中返回的數(shù)據(jù), 所以這里采用發(fā)布訂閱模式來做
完整代碼在最后,不想看我廢話的可以直接扒拉了
步驟就是: 連接,頁面發(fā)送消息,接收消息,over ~
首先定義連接websocket的方法
export default class SocketService { constructor(url){ this.url = url }, connect() { //判斷瀏覽器是否支持websocket if (!window.WebSocket) { return console.log("您的瀏覽器不支持WebSocket"); } url, //連接websocket this.ws = new WebSocket(this.url); //監(jiān)聽websocket各種狀態(tài) this.ws.onopen = () => {}; this.ws.onclose = () => {}; this.ws.onerror = () => {}; this.ws.onmessage = (e) => {}; } }
我們先讓socket連接上叭
export default class SocketService { constructor(url, againConnect = true){ this.url = url this.againConnect = againConnect; }, ws = null; // 和服務(wù)端連接的socket對象 url; //地址 againConnect; //標(biāo)識(shí)斷開是否重連 connected = false; // 標(biāo)識(shí)是否連接成功 sendRetryCount = 0; // 記錄重試的次數(shù) connectRetryCount = 0; // 重新連接嘗試的次數(shù) connect() { //判斷瀏覽器是否支持websocket if (!window.WebSocket) { return console.log("您的瀏覽器不支持WebSocket"); } url, //連接websocket this.ws = new WebSocket(this.url); //監(jiān)聽websocket各種狀態(tài) this.ws.onopen = () => { //連接上后所有標(biāo)識(shí)清零 this.connected = true; this.connectRetryCount = 0; }; this.ws.onclose = () => { //連接關(guān)閉 this.connected = false; this.connectRetryCount++; if (this.againConnect) { //重連 setTimeout(() => { this.connect(); }, 500 * this.connectRetryCount); } else { //不重連的操作 sessionStorage.clear(); localStorage.clear(); message.error("登錄超時(shí)"); router.push("/"); } }; this.ws.onerror = () => { //連接失敗 this.connected = false; this.connectRetryCount++; if (this.againConnect) { setTimeout(() => { this.connect(); }, 500 * this.connectRetryCount); } }; this.ws.onmessage = (e) => { console.log(e) }; }, unSubscribe() {} send(){ //發(fā)送消息的方法 } }
那么我們要怎么給后端發(fā)送消息呢,發(fā)送了消息之后我們又該怎樣才能在頁面中接收到消息呢?
在send方法中接收一個(gè)回調(diào)函數(shù),
在message中調(diào)用,
subscribeList = {}; //記載回調(diào)函數(shù) idList = []; send(data, callback) { //判斷此時(shí)有沒有ws if (!this.ws) { this.connect(); this.send(data, callback); } else { // 判斷此時(shí)此刻有沒有連接成功 if (this.connected) { this.sendRetryCount = 0; this.ws.send(JSON.stringify(data)); if (data.type === "sub") { //存儲(chǔ)id this.idList.push(data.id); //存儲(chǔ)回調(diào)函數(shù), if (!this.subscribeList[data.id]) { this.subscribeList[data.id] = [callback]; } else { this.subscribeList[data.id].push(callback); } } } else { this.sendRetryCount++; setTimeout(() => { this.send(data, callback); }, this.sendRetryCount * 500); } } } connect(){ ...... this.ws.onmessage = (e) => { let { payload, requestId, type } = JSON.parse(e.data); if (type === "error") { console.log("出錯(cuò)了"); } if (this.subscribeList[requestId]) { if (type === "complete") { console.log("完成了"); } else if (type === "result") { this.subscribeList[requestId].forEach((item) => item.call(this, payload) ); } } }; } //銷毀回調(diào)函數(shù) unSubscribe() { //停止消息發(fā)送 this.idList.forEach((item) => { this.send({ id: item, type: "unsub" }); delete this.subscribeList[item]; }); this.idList = []; }
sub標(biāo)識(shí)發(fā)送消息, unsub標(biāo)識(shí)停止發(fā)送消息
id為事件的標(biāo)識(shí)符
現(xiàn)在解決了頁面中接收消息的問題,那么怎么保證離開頁面,回到頁面,使用的是同一個(gè)websocket呢,如果實(shí)例化這個(gè)類的話,那么每次進(jìn)入都會(huì)實(shí)例化SocketService,
es6的class中有取值函數(shù)和存值函數(shù), 具體使用請看這里:
Class 的基本語法 - ES6 教程 - 網(wǎng)道 (wangdoc.com)
instance = null; static get Instance() { if (!this.instance) { this.instance = new SocketService(false); } return this.instance; }
使用getter,來拿取class中的instance,拿取的時(shí)候設(shè)置攔截該行為,判斷instance有沒有值,沒有值就實(shí)例化SocketService給instance,返回instance,
import SocketService from "@/websocket/websocket"; mounted() { this.ws = SocketService.Instance; this.ws.send( { id: "11111", topic: "/xxx/xxx", parameter: {}, type: "sub", }, this.Callback ); } destroyed() { this.ws.unSubscribe(); }, methods:{ Callback(data) { console.log(data); }, }
export default class SocketService { constructor(againConnect = true, url) { this.url = url; this.againConnect = againConnect; } instance = null; //頁面中使用的SocketService實(shí)例 ws = null; // 和服務(wù)端連接的socket對象 url; //地址 againConnect; //斷開是否重連 connected = false; // 標(biāo)識(shí)是否連接成功 sendRetryCount = 0; // 記錄重試的次數(shù) connectRetryCount = 0; // 重新連接嘗試的次數(shù) //單例模式保證只有一個(gè)SocketService實(shí)例 static get Instance() { if (!this.instance) { this.url = '......' this.instance = new SocketService(false, url); } return this.instance; } // 定義連接服務(wù)器的方法 connect() { // 這里判斷你的瀏覽器支不支持websocket if (!window.WebSocket) { return console.log("您的瀏覽器不支持WebSocket"); } this.ws = new WebSocket(this.url); //連接上了 this.ws.onopen = () => { this.connected = true; // 重置重新連接的次數(shù) this.connectRetryCount = 0; }; //連接關(guān)閉了,設(shè)置標(biāo)識(shí)值為false, this.ws.onclose = () => { this.connected = false; this.connectRetryCount++; if (this.againConnect) { setTimeout(() => { this.connect(); }, 500 * this.connectRetryCount); } else { sessionStorage.clear(); localStorage.clear(); message.error("登錄超時(shí)"); router.push("/"); } }; this.ws.onerror = () => { console.log("socket連接失敗"); this.connected = false; this.connectRetryCount++; if (this.againConnect) { setTimeout(() => { this.connect(); }, 500 * this.connectRetryCount); } }; this.ws.onmessage = (e) => { let { payload, requestId } = JSON.parse(e.data); if (this.subscribeList[requestId]) { this.subscribeList[requestId].forEach((item) => item.call(this, payload) ); } }; } //銷毀回調(diào)函數(shù) unSubscribe() { //停止消息發(fā)送 this.idList.forEach((item) => { this.send({ id: item, type: "unsub" }); delete this.subscribeList[item]; }); this.idList = []; } subscribeList = {}; //記載回調(diào)函數(shù) idList = []; // 發(fā)送數(shù)據(jù)的方法 send(data, callback) { //判斷此時(shí)有沒有ws if (!this.ws) { this.connect(); this.send(data, callback); } else { // 判斷此時(shí)此刻有沒有連接成功 if (this.connected) { this.sendRetryCount = 0; this.ws.send(JSON.stringify(data)); if (data.type === "sub") { //存儲(chǔ)id this.idList.push(data.id); //存儲(chǔ)回調(diào)函數(shù), if (!this.subscribeList[data.id]) { this.subscribeList[data.id] = [callback]; } else { this.subscribeList[data.id].push(callback); } } } else { this.sendRetryCount++; setTimeout(() => { this.send(data, callback); }, this.sendRetryCount * 500); } } } }
感謝各位的閱讀,以上就是“websocket在vue2中如何封裝使用”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對websocket在vue2中如何封裝使用這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。