记录一次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 相关文章推荐
了解jQuery技巧来提高你的代码
Jan 08 Javascript
取得窗口大小 兼容所有浏览器的js代码
Aug 09 Javascript
javascript针对DOM的应用分析(四)
Apr 15 Javascript
JavaScript中遍历对象的property的3种方法介绍
Dec 30 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
Mar 14 Javascript
JavaScript制作windows经典扫雷小游戏
Mar 31 Javascript
浅谈javascript事件取消和阻止冒泡
May 26 Javascript
js时间比较 js计算时间差的简单实现方法
Aug 26 Javascript
react系列从零开始_简单谈谈react
Jul 06 Javascript
浅谈js中的this问题
Aug 31 Javascript
JavaScript门面模式详解
Oct 19 Javascript
浅谈Vue.js 组件中的v-on绑定自定义事件理解
Nov 17 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编写的简单页面跳转功能实现代码
2013/11/27 PHP
php实现微信公众平台账号自定义菜单类
2015/10/11 PHP
PHP中for循环与foreach的区别
2017/03/06 PHP
Avengerls vs KG BO3 第三场2.18
2021/03/10 DOTA
javascript编程起步(第七课)
2007/02/27 Javascript
jQuery 判断元素上是否绑定了事件
2009/10/28 Javascript
namespace.js Javascript的命名空间库
2011/10/11 Javascript
js动态在form上插入enctype=multipart/form-data的问题
2012/05/24 Javascript
Javascript的常规数组和关联数组对比小结
2012/05/24 Javascript
jQuery+css+html实现页面遮罩弹出框
2013/03/21 Javascript
Jquery解析Json格式数据过程代码
2014/10/17 Javascript
JavaScript实现获取dom中class的方法
2015/02/09 Javascript
ECMAScript6中Map/WeakMap详解
2015/06/12 Javascript
JS实现带鼠标效果的头像及文章列表代码
2015/09/27 Javascript
JavaScript中apply方法的应用技巧小结
2016/09/29 Javascript
深入理解Node.js 事件循环和回调函数
2016/11/02 Javascript
微信小程序进行微信支付的步骤昂述
2016/12/01 Javascript
Three.js如何用轨迹球插件(trackball)增加对模型的交互功能详解
2017/09/25 Javascript
JS实现自定义状态栏动画文字效果示例
2017/10/12 Javascript
Angular移动端页面input无法输入的解决方法
2017/11/14 Javascript
vue环形进度条组件实例应用
2018/10/10 Javascript
js表达式与运算符简单操作示例
2020/02/15 Javascript
Python中的自省(反射)详解
2015/06/02 Python
tensorflow学习笔记之简单的神经网络训练和测试
2018/04/15 Python
三步实现Django Paginator分页的方法
2019/06/11 Python
pandas中的series数据类型详解
2019/07/06 Python
Python实现快速大文件比较代码解析
2020/09/04 Python
使用CSS3实现input多选框自定义样式的方法示例
2019/07/19 HTML / CSS
Gap加拿大官网:Gap Canada
2017/08/24 全球购物
工程专业应届生求职信
2014/02/19 职场文书
安全生产中长期规划实施方案
2014/02/21 职场文书
老公保证书怎么写
2015/02/26 职场文书
关于运动会的广播稿
2015/08/19 职场文书
2016党性教育学习心得体会
2016/01/21 职场文书
导游词之黄帝陵景区
2019/09/16 职场文书
浅谈Golang 切片(slice)扩容机制的原理
2021/06/09 Golang