欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

websocket在vue2中的封裝使用方式

 更新時間:2024年08月09日 10:17:14   作者:子恒吃西瓜  
這篇文章主要介紹了websocket在vue2中的封裝使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

websocket在vue2中的封裝使用

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

實現(xiàn)思路

  • 因為是全局連接一個websocket,所以這里采用單例模式
  • 也是因為封裝的原因,頁面中肯定是直接拿不到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;         // 和服務端連接的socket對象
      url;               //地址
      againConnect;      //標識斷開是否重連
      connected = false; // 標識是否連接成功
      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 = () => {
            //連接上后所有標識清零
            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("登錄超時");
                 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ā)送了消息之后我們又該怎樣才能在頁面中接收到消息呢?

subscribeList = {}; //記載回調(diào)函數(shù)
idList = [];
send(data, callback) {
    //判斷此時有沒有ws
    if (!this.ws) {
      this.connect();
      this.send(data, callback);
    } else {
      // 判斷此時此刻有沒有連接成功
      if (this.connected) {
        this.sendRetryCount = 0;
        this.ws.send(JSON.stringify(data));
        if (data.type === "sub") {
          //存儲id
          this.idList.push(data.id);
          //存儲回調(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("出錯了");
      }
      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 = [];
 }

1.在send方法中接收一個回調(diào)函數(shù)

  • sub標識發(fā)送消息, unsub標識停止發(fā)送消息
  • id為事件的標識符

2.在message中調(diào)用

現(xiàn)在解決了頁面中接收消息的問題,那么怎么保證離開頁面,回到頁面,使用的是同一個websocket呢,如果實例化這個類的話,那么每次進入都會實例化SocketService,

instance = null;
static get Instance() {
    if (!this.instance) {
      this.instance = new SocketService(false);
    }
    return this.instance;
 }

1.es6的class中有取值函數(shù)和存值函數(shù), 具體使用請看這里:

2.Class 的基本語法 - ES6 教程 - 網(wǎng)道

  • 使用getter,來拿取class中的instance,拿取的時候設置攔截該行為,判斷instance有沒有值,沒有值就實例化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實例
  ws = null; // 和服務端連接的socket對象
  url; //地址
  againConnect;     //斷開是否重連
  connected = false; // 標識是否連接成功
  sendRetryCount = 0; // 記錄重試的次數(shù)
  connectRetryCount = 0; // 重新連接嘗試的次數(shù)
    
  //單例模式保證只有一個SocketService實例
  static get Instance() {
    if (!this.instance) {
        this.url = '......'
      this.instance = new SocketService(false, url);
    }
    return this.instance;
  }
  //  定義連接服務器的方法
  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)閉了,設置標識值為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("登錄超時");
        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) {
    //判斷此時有沒有ws
    if (!this.ws) {
      this.connect();
      this.send(data, callback);
    } else {
      // 判斷此時此刻有沒有連接成功
      if (this.connected) {
        this.sendRetryCount = 0;
        this.ws.send(JSON.stringify(data));

        if (data.type === "sub") {
          //存儲id
          this.idList.push(data.id);
          //存儲回調(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);
      }
    }
  }
}

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • VSCode Vue開發(fā)推薦插件和VSCode快捷鍵(小結(jié))

    VSCode Vue開發(fā)推薦插件和VSCode快捷鍵(小結(jié))

    這篇文章主要介紹了VSCode Vue開發(fā)推薦插件和VSCode快捷鍵(小結(jié)),文中通過圖文表格介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • vue.js前后端數(shù)據(jù)交互之提交數(shù)據(jù)操作詳解

    vue.js前后端數(shù)據(jù)交互之提交數(shù)據(jù)操作詳解

    這篇文章主要介紹了vue.js前后端數(shù)據(jù)交互之提交數(shù)據(jù)操作,結(jié)合實例形式較為詳細的分析了vue.js前后端數(shù)據(jù)交互相關(guān)的表單結(jié)構(gòu)、約束規(guī)則、數(shù)據(jù)提交等相關(guān)操作技巧與注意事項,需要的朋友可以參考下
    2018-04-04
  • vue中destroyed方法及使用示例講解

    vue中destroyed方法及使用示例講解

    這篇文章主要為大家介紹了vue中destroyed方法及使用示例講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • 詳解vue3.2中setup語法糖<script?lang="ts"?setup>

    詳解vue3.2中setup語法糖<script?lang="ts"?setup>

    Vue 3.2 引入了語法,這是一種稍微不那么冗長的聲明組件的方式,下面這篇文章主要介紹了詳解vue3.2中setup語法糖<script?lang="ts"setup>的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • vue中標簽自定義屬性的使用及說明

    vue中標簽自定義屬性的使用及說明

    這篇文章主要介紹了vue中標簽自定義屬性的使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Vue+springboot批量刪除功能實現(xiàn)代碼

    Vue+springboot批量刪除功能實現(xiàn)代碼

    這篇文章主要介紹了Vue+springboot批量刪除功能,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • vscode配置vue下的es6規(guī)范自動格式化詳解

    vscode配置vue下的es6規(guī)范自動格式化詳解

    這篇文章主要介紹了vscode配置vue下的es6規(guī)范自動格式化詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • 如何手寫一個簡易的 Vuex

    如何手寫一個簡易的 Vuex

    這篇文章主要介紹了如何手寫一個簡易的 Vuex,幫助大家更好的理解和學習vue,感興趣的朋友可以了解下
    2020-10-10
  • vue動態(tài)設置路由權(quán)限的主要思路

    vue動態(tài)設置路由權(quán)限的主要思路

    這篇文章主要給大家介紹了關(guān)于vue動態(tài)設置路由權(quán)限的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • vue+axios實現(xiàn)post文件下載

    vue+axios實現(xiàn)post文件下載

    這篇文章主要為大家詳細介紹了vue+axios實現(xiàn)post文件下載,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09

最新評論