溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

websocket在vue2中如何封裝使用

發(fā)布時(shí)間:2023-03-09 14:09:59 來源:億速云 閱讀:122 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“websocket在vue2中如何封裝使用”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“websocket在vue2中如何封裝使用”吧!

    websocket在vue2中的封裝使用

    先說需求: 頁面中有websocket連接,進(jìn)入的時(shí)候發(fā)送參數(shù)到后端,后端發(fā)送消息, 離開頁面時(shí)發(fā)送參數(shù)至后端,后端停止發(fā)送消息,不得斷開連接, 下一次進(jìn)入時(shí)頁面時(shí)不用再次連接。

    實(shí)現(xiàn)思路:

    • 因?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);
         },
     }

    在vue中的封裝

     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)注!

    向AI問一下細(xì)節(jié)

    免責(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)容。

    AI