验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

websocket在vue2中如何封装使用

阅读:1137 来源:乙速云 作者:代码code

websocket在vue2中如何封装使用

      websocket在vue2中的封装使用

      先说需求: 页面中有websocket连接,进入的时候发送参数到后端,后端发送消息, 离开页面时发送参数至后端,后端停止发送消息,不得断开连接, 下一次进入时页面时不用再次连接。

      实现思路:

      • 因为是全局连接一个websocket,所以这里采用单例模式

      • 也是因为封装的原因,页面中肯定是直接拿不到onmessage中返回的数据, 所以这里采用发布订阅模式来做

      完整代码在最后,不想看我废话的可以直接扒拉了

      步骤

      步骤就是: 连接,页面发送消息,接收消息,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);
               //监听websocket各种状态
               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; // 记录重试的次数
             connectRetryCount = 0; // 重新连接尝试的次数
           connect() {
               //判断浏览器是否支持websocket
               if (!window.WebSocket) {
                 return console.log("您的浏览器不支持WebSocket");
               }
               url,
              //连接websocket
               this.ws = new WebSocket(this.url);
               //监听websocket各种状态
               this.ws.onopen = () => {
                   //连接上后所有标识清零
                   this.connected = true;
                   this.connectRetryCount = 0;
               };
               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 = () => {
                   //连接失败
                     this.connected = false;
                     this.connectRetryCount++;
                     if (this.againConnect) {
                       setTimeout(() => {
                         this.connect();
                       }, 500 * this.connectRetryCount);
                     }
               };
               this.ws.onmessage = (e) => {
                   console.log(e)
               };
           },
           unSubscribe() {}
           send(){
               //发送消息的方法
           }
       }

      那么我们要怎么给后端发送消息呢,发送了消息之后我们又该怎样才能在页面中接收到消息呢?

      在send方法中接收一个回调函数,

      在message中调用,

       subscribeList = {}; //记载回调函数
       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);
                 //存储回调函数,
                 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)
                 );
               }
             }
           };
       }
       //销毁回调函数
         unSubscribe() {
           //停止消息发送
           this.idList.forEach((item) => {
             this.send({ id: item, type: "unsub" });
             delete this.subscribeList[item];
           });
           this.idList = [];
        }
      • sub标识发送消息, unsub标识停止发送消息

      • id为事件的标识符

      现在解决了页面中接收消息的问题,那么怎么保证离开页面,回到页面,使用的是同一个websocket呢,如果实例化这个类的话,那么每次进入都会实例化SocketService,

      es6的class中有取值函数和存值函数, 具体使用请看这里:

      Class 的基本语法 - ES6 教程 - 网道 (wangdoc.com)

       instance = null;
       static get Instance() {
           if (!this.instance) {
             this.instance = new SocketService(false);
           }
           return this.instance;
        }
      • 使用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; // 记录重试的次数
         connectRetryCount = 0; // 重新连接尝试的次数
         //单例模式保证只有一个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;
             // 重置重新连接的次数
             this.connectRetryCount = 0;
           };
             //连接关闭了,设置标识值为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)
                 );
               }
           };
         }
         //销毁回调函数
         unSubscribe() {
           //停止消息发送
           this.idList.forEach((item) => {
             this.send({ id: item, type: "unsub" });
             delete this.subscribeList[item];
           });
           this.idList = [];
         }
         subscribeList = {}; //记载回调函数
         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);
                 //存储回调函数,
                 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);
             }
           }
         }
       }
    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>