记录一次websocket封装的过程


Posted in Javascript onNovember 23, 2020

在一个应用中,websocket一般都是以单例形式存在的,即在整个应用中,websocket实例始终保持唯一。但有时我们要用到websocket实例的时候,可能websocket还没实例化,所以要做成异步的形式来获取实例。

一、封装。先创建 socket.ts 文件

import EventEmitter from 'events'; // 这里用到了 events 包
const ee = new EventEmitter();
class Ws {
 private wsUrl: string = '';
 private socket: WebSocket | undefined; // socket实例
 private lockReconnect: boolean = false; // 重连锁
 private timeout: NodeJS.Timeout | undefined;

 // 初始化socket,一般在应用启动时初始化一次就好了,或者需要更换wsUrl
 public init(wsUrl: string) {
  this.wsUrl = wsUrl;
  this.createWebSocket();
 }

 // 获取socket实例
 public getInstance(): Promise<WebSocket> {
  return new Promise((resolve, reject) => {
   if (this.socket) {
    resolve(this.socket);
   } else {
    ee.on('socket', (state: string) => {
     if (state === 'success') {
      resolve(this.socket);
     } else {
      reject();
     }
    });
   }
  });
 }

 // 创建socket
 private createWebSocket() {
  try {
   console.log('websocket 开始链接');
   const socket = new WebSocket(this.wsUrl);
   socket.addEventListener('close', () => {
    console.log('websocket 链接关闭');
    this.socket = undefined;
    this.reconnect();
   });
   socket.addEventListener('error', () => {
    console.log('websocket 发生异常了');
    this.socket = undefined;
    this.reconnect();
   });
   socket.addEventListener('open', () => {
    // 可在此进行心跳检测
    // this.heartCheck.start();
    console.log('websocket open');
    this.socket = socket;
    ee.emit('socket', 'success');
   });
   socket.addEventListener('message', (event) => {
    console.log('websocket 接收到消息', event);
   });
  } catch (e) {
   console.log('socket catch error', e);
   this.reconnect();
  }
 }

 // 重连
 private reconnect() {
  if (this.lockReconnect) {
   return;
  }
  console.log('websocket 正在重新连接');
  this.lockReconnect = true;
  //没连接上会一直重连,设置延迟避免请求过多
  this.timeout && clearTimeout(this.timeout);
  this.timeout = setTimeout(() => {
   this.createWebSocket();
   this.lockReconnect = false;
  }, 5000);
 }
}

export default new Ws();

二、引入并使用

import socket from '@/utils/ws';

socket
 .getInstance()
 .then((ws) => {
   // 这里的 ws 就是实例化后的 websocket,可以直接使用 websocket 原生 api
  console.log('getInstance ws', ws);
  ws.addEventListener('message', (event) => {
    console.log('ws 接收到消息', event);
   });
 })
 .catch(() => {});

以上就是记录一次websocket封装的过程的详细内容,更多关于websocket封装的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
可拖动窗口,附带鼠标控制渐变透明,开启关闭功能
Jun 26 Javascript
再谈javascript 动态添加样式规则 W3C校检
Dec 25 Javascript
Bookmarklet实现启动jQuery(模仿 云输入法)
Sep 15 Javascript
工作需要写的一个js拖拽组件
Jul 28 Javascript
深入理解JavaScript系列(15) 函数(Functions)
Apr 12 Javascript
Javascript获取当前日期的农历日期代码
Oct 08 Javascript
直接拿来用的页面跳转进度条JS实现
Jan 06 Javascript
简单谈谈require模块化jquery和angular的问题
Jun 23 jQuery
node.js利用mongoose获取mongodb数据的格式化问题详解
Oct 06 Javascript
Element UI 自定义正则表达式验证方法
Sep 04 Javascript
详解vue高级特性
Jun 09 Javascript
element中Steps步骤条和Tabs标签页关联的解决
Dec 08 Javascript
一篇文章让你搞懂JavaScript 原型和原型链
Nov 23 #Javascript
微信小程序实现锚点跳转
Nov 23 #Javascript
javascript实现电商放大镜效果
Nov 23 #Javascript
用webAPI实现图片放大镜效果
Nov 23 #Javascript
Vue 的 v-model用法实例
Nov 23 #Vue.js
JavaScript实现网页留言板功能
Nov 23 #Javascript
VUE+Element实现增删改查的示例源码
Nov 23 #Vue.js
You might like
细谈php中SQL注入攻击与XSS攻击
2012/06/10 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
php实现微信公众平台发红包功能
2018/06/14 PHP
Laravel框架自定义分页样式操作示例
2020/01/26 PHP
javascript下arguments,caller,callee,call,apply示例及理解
2009/12/24 Javascript
Javascript学习笔记7 原型链的原理
2010/01/11 Javascript
jQuery timers计时器简单应用说明
2010/10/28 Javascript
jquery增加和删除元素的方法
2015/01/14 Javascript
JavaScript获取伪元素(Pseudo-Element)属性的方法技巧
2015/03/13 Javascript
JavaScript操作XML/HTML比较常用的对象属性集锦
2015/10/30 Javascript
JavaScript和jQuery制作光棒效果
2017/02/24 Javascript
jQuery EasyUI Panel面板组件使用详解
2017/02/28 Javascript
js弹出窗口简单实现代码
2017/03/22 Javascript
详解js静态资源文件请求的处理
2017/08/01 Javascript
详细分析jsonp的原理和实现方式
2017/11/20 Javascript
vue给组件传递不同的值方法
2018/09/29 Javascript
原生JS实现随机点名项目的实例代码
2019/04/30 Javascript
node express使用HTML模板的方法示例
2019/08/22 Javascript
Nodejs文件上传、监听上传进度的代码
2020/03/27 NodeJs
Vue微信公众号网页分享的示例代码
2020/05/28 Javascript
vue实现拖拽进度条
2021/03/01 Vue.js
[01:04:01]2014 DOTA2华西杯精英邀请赛5 24 DK VS VG
2014/05/25 DOTA
[35:55]完美世界DOTA2联赛PWL S3 Rebirth vs CPG 第一场 12.11
2020/12/13 DOTA
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
Python实现分段线性插值
2018/12/17 Python
如何基于python实现脚本加密
2019/12/28 Python
如何使用python传入不确定个数参数
2020/02/18 Python
matplotlib.pyplot.matshow 矩阵可视化实例
2020/06/16 Python
tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this T
2020/06/22 Python
Burberry英国官网:英国标志性奢侈品牌
2017/03/29 全球购物
欧洲最大的品牌水上运动服装和设备在线零售商:Wuituit Outlet
2018/05/05 全球购物
英国最大的汽车配件在线商店:Euro Car Parts
2019/09/30 全球购物
意大利在线眼镜精品店:Ottica Lipari
2019/11/11 全球购物
致跳远运动员广播稿
2014/02/11 职场文书
公司授权委托书范本
2014/04/03 职场文书
HttpClient实现表单提交上传文件
2022/08/14 Java/Android