记录一次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的超简单上下翻
Apr 20 Javascript
javascript Array数组对象的扩展函数代码
May 22 Javascript
js 判断脚本加载完毕的代码
Jul 13 Javascript
jQuery使用数组编写图片无缝向左滚动
Dec 11 Javascript
js遍历td tr等html元素
Dec 13 Javascript
用js写了一个类似php的print_r输出换行功能
Feb 18 Javascript
Select标签下拉列表二级联动级联实例代码
Feb 07 Javascript
jQuery及JS实现循环中暂停的方法
Feb 02 Javascript
vue、react等单页面项目应该这样子部署到服务器
Jan 03 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
Aug 09 jQuery
JavaScript常用工具函数汇总(浏览器环境)
Sep 17 Javascript
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 Vue.js
一篇文章让你搞懂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
纯真IP数据库的应用 IP地址转化成十进制
2009/06/14 PHP
解析PHP实现下载文件的两种方法
2013/07/05 PHP
PHP中执行MYSQL事务解决数据写入不完整等情况
2014/01/07 PHP
在Laravel中实现使用AJAX动态刷新部分页面
2019/10/15 PHP
laravel框架中控制器的创建和使用方法分析
2019/11/23 PHP
Laravel中如何轻松容易的输出完整的SQL语句
2020/07/26 PHP
PHP时间类完整代码实例
2021/02/26 PHP
网页设计常用的一些技巧
2006/12/22 Javascript
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
JavaScript中用toString()方法返回时间为字符串
2015/06/12 Javascript
JavaScript实现单击下拉框选择直接跳转页面的方法
2015/07/02 Javascript
JS实现仿QQ效果的三级竖向菜单
2015/09/25 Javascript
Angular 4.x中表单Reactive Forms详解
2017/04/25 Javascript
JavaScript实现单击网页任意位置打开新窗口与关闭窗口的方法
2017/09/21 Javascript
JS实现的哈夫曼编码示例【原始版与修改版】
2018/04/22 Javascript
JavaScript中常用的简洁高级技巧总结
2019/03/10 Javascript
js+for循环实现字符串自动转义的代码(把后面的字符替换前面的字符)
2020/12/24 Javascript
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
Python 3.x 连接数据库示例(pymysql 方式)
2017/01/19 Python
对Python信号处理模块signal详解
2019/01/09 Python
Pycharm 2019 破解激活方法图文详解
2019/10/11 Python
在Python IDLE 下调用anaconda中的库教程
2020/03/09 Python
Python 实现平台类游戏添加跳跃功能
2020/03/27 Python
Django模板获取field的verbose_name实例
2020/05/19 Python
Python中socket网络通信是干嘛的
2020/05/27 Python
HTML5拖放功能_动力节点Java学院整理
2017/07/13 HTML / CSS
全国道德模范事迹
2014/02/01 职场文书
人大调研汇报材料
2014/08/14 职场文书
领导班子四风对照检查材料范文
2014/09/27 职场文书
运动会报道稿大全
2015/07/23 职场文书
勤俭节约主题班会
2015/08/13 职场文书
小学生作文之《压岁钱的烦恼》
2019/09/27 职场文书
在CSS中映射鼠标位置并实现通过鼠标移动控制页面元素效果(实例代码)
2021/04/22 HTML / CSS
MySQL数据库超时设置配置的方法实例
2021/10/15 MySQL
python 标准库原理与用法详解之os.path篇
2021/10/24 Python
疑《守望先锋2》A测截图泄露 或将推出新模式、新界面
2022/04/03 其他游戏