封装websocket并在vuejs中调用

15 篇文章 0 订阅

websocket 事件说明
open:连接成功时触发。
message:收到数据时触发。
error:连接失败时触发。
close:连接被关闭时触发。
以下情况下触发close和error:
1、客户端主动关闭websocket时触发close事件。
2、成功连接websocket后服务器断开时触发close事件。
3、成功连接websocket后断开网络,触发close事件。
4、先断网后连接websocket,先触发error事件,再触发close事件。
5、网络通畅的情况下,连接websocket不成功时,先触发error, 再触发close(选定)
综上,各种异常情况下都会触发close, 各种断开重连的操作,最好放在close事件下。

//  封装websocket
 export default class CeWebsocketUtil {
  constructor (that) {
    this.maxReConnectTimes = 10; // 最大连接次数,默认10次
    this.reIntervalTime = 30 * 1000; // 重连间隔时间,默认30秒
    this.currentComponent = that;
    this.websocket = null;
    this.reConnectTimes = 0; // 失败后重新连接次数
  }

  /**
   * 初始化Websocket连接
   * @param {*} url ws连接url
   */
  initWebsocket (url) {
    if (!url) return;
    this.websocket && this.closeWebsocket();
    this.websocket = new WebSocket(url);
    this.websocket.onopen = () => this.onOpenFn();
    this.websocket.onmessage = e => this.onMessageFn(e);
    this.websocket.onerror = () => {
      console.log('onerror:连接失败');
    };
    // 每次报error之后都会调用close,所以连接失败和断开连接的处理都写在close中
    this.websocket.onclose = e => {
      this.onCloseFn();
    };
  }

  /*
   * 连接成功
   */
  onOpenFn () {
    const NowFormatter = this.formatDateTime();
    if (this.reConnectTimes > 0) {
      console.info(`ws重连:第【${this.reConnectTimes}】次连接成功!
      ****${this.websocket.url}****${NowFormatter}`);
    } else {
      console.info(`ws连接成功****${this.websocket.url}****${NowFormatter}`);
      this.reConnectTimes = 0;
    }
    // 注册onWsOpen方法
    this.currentComponent.onWsOpen();
  }

  /**
   * 收到消息
   * @param {*} e 消息事件
   */
  onMessageFn (e) {
    console.info(`ws收到消息****${this.websocket.url}****${e.data}`);
    // 注册onWsMessage方法,接收消息
    this.currentComponent.onWsMessage(e.data);
  }

  /**
   * 重新连接
   */
  reConnect () {
    // 先关掉 再连接
    this.websocket && this.websocket.close();
    const NowFormatter = this.formatDateTime();
    this.reConnectTimes += 1;
    console.info(`ws重连:正在尝试第【${this.reConnectTimes}】次连接:****${this.websocket.url}****${NowFormatter}`);
    if (this.websocket && this.websocket.url) {
      this.initWebsocket(this.websocket.url);
    }
  }

  /**
   * 关闭连接
   */
  closeWebsocket () {
    console.info('WEB端主动关闭websocket');
    if (this.websocket) {
    	this.websocket.close();
    	this.websocket = null;
    } 
  }

  // 关闭连接
  onCloseFn () {
    const NowFormatter = this.formatDateTime();
    console.error(`ws断开连接****${NowFormatter}`);
    if (this.currentComponent && !this.currentComponent.manualClose && this.websocket && this.websocket.url) {
      if (this.reConnectTimes < this.maxReConnectTimes) {
        console.error(`ws断开连接,需要${this.reIntervalTime / 1000}秒后重连****${this.websocket.url}****${NowFormatter}`);
        setTimeout(() => {
          this.websocket && this.websocket.url && this.reConnect();
        }, this.reIntervalTime);
      } else {
        console.error(`ws重连第【${this.reConnectTimes}】次,不再重连`);
      }
    }
  }

  /**
   * 发送心跳
   * @param {*} data
   */
  sendData (data) {
    if (this.websocket && this.websocket.readyState === 1) {
      console.info(`sendData${JSON.stringify(data)}`);
      this.websocket.send(JSON.stringify(data));
    } else {
		console.error('websocket未连接');
	}
  }

  /**
   * 格式化new Date() YYYY-MM-DD HH:mm:ss:ms
   * @returns
   */
  formatDateTime () {
    const Now = new Date();
    return `${Now.getFullYear()}-${
      Now.getMonth() + 1
    }-${Now.getDate()} ${Now.getHours()}:${Now.getMinutes()}:${Now.getSeconds()}:${Now.getMilliseconds()}`;
  }
}

2、VUE组件中
2.1 引入封装好的websocket

import CeWebsocketUtil  from '@common/ce-websocket-util';
export default {
	data () {
      	return {
      		ws: null, 
      		manualClose: false, // 是否手动关闭ws
      	}
      }
}

2.2、创建连接,初始化数据

this.ws = new CeWebsocketUtil(this);
const URL = `ws://*****`;
this.ws.initWebsocket(URL);

2.3、 websocket 连接成功

onWsOpen () {
 	console.log('websocket已连接成功');
 	this.manualClose = false;
},

2.4、发送心跳

this.ws.sendData({ rule: "hello world" });

2.5、 接收websocket数据

onWsMessage (e) {
    // TODO: 处理接收的数据
}

2.6、主动关闭websocket

if (this.ws) {
	this.manualClose = true;
	this.ws.closeWebsocket();
}
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3 ,可以通过自定义一个 WebSocketVue 插件来封装 WebSocket 功能,具体步骤如下: 1. 创建一个 vue-websocket.js 文件,代码如下: ```javascript class WebSocketPlugin { constructor(url) { this.url = url; this.websocket = null; this.onMessageCallbacks = []; } connect() { this.websocket = new WebSocket(this.url); this.websocket.onopen = () => { console.log('WebSocket opened'); }; this.websocket.onclose = () => { console.log('WebSocket closed'); }; this.websocket.onmessage = (event) => { this.onMessageCallbacks.forEach((callback) => { callback(JSON.parse(event.data)); }); }; } send(data) { this.websocket.send(JSON.stringify(data)); } onMessage(callback) { this.onMessageCallbacks.push(callback); } } export default { install: (app, options) => { const ws = new WebSocketPlugin(options.url); app.config.globalProperties.$ws = ws; app.provide('ws', ws); ws.connect(); }, }; ``` 2. 在 main.js 注册该插件,代码如下: ```javascript import { createApp } from 'vue'; import App from './App.vue'; import WebSocketPlugin from './vue-websocket'; const app = createApp(App); app.use(WebSocketPlugin, { url: 'ws://localhost:8080' }); app.mount('#app'); ``` 3. 在 Vue 组件使用 WebSocket,代码如下: ```javascript <template> <div> <button @click="send">Send</button> </div> </template> <script> export default { mounted() { this.$ws.onMessage((data) => { console.log(data); }); }, methods: { send() { this.$ws.send({ message: 'Hello WebSocket' }); }, }, }; </script> ``` 以上是一个简单的 Vue3 封装 WebSocket 的示例代码,可以根据自己的需求进行修改和扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值