uno-ws-client
Version:
websocket客户端
260 lines (215 loc) • 6.42 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import { merge } from 'lodash-es';
var defaultOptions = {
autoConnect: true,
reconnectionDelay: 2000,
heartbeatDelay: 20000,
heartbeatWait: 2000,
connectByClose: true,
reconnectionLimit: 10
};
export var Ws = /*#__PURE__*/function () {
// 服务端ws地址
// 当前链接注册内容
// 当前链接实例
// 心跳检测间隔
// 断开重连次数限制
// 是否正在心跳检测中
// 重连setTimeout id
// 心跳检测定时id
// 心跳检测延时id
function Ws(url, options) {
this.options = void 0;
this.wsUrl = void 0;
this.registerData = void 0;
this.ins = void 0;
this.heartbeatDelay = defaultOptions.heartbeatDelay;
this.reconnectionLimit = defaultOptions.reconnectionLimit;
this.hearting = void 0;
this.reconnectId = void 0;
this.hbId = void 0;
this.hbId_s = void 0;
this.loadCb = void 0;
this.options = _extends({}, defaultOptions, options);
this.wsUrl = url; // 自动连接
if (this.options.autoConnect) {
this.init();
}
}
/**
* 初始化
*/
var _proto = Ws.prototype;
_proto.init = function init() {
if (this.ins) {
this.destroy();
}
this.reconnectionLimit = this.options.reconnectionLimit;
this.heartbeatDelay = this.options.heartbeatDelay;
this.registerData = this.options.registerData;
if (!this.wsUrl) {
// eslint-disable-next-line no-console
console.error('请配置服务地址');
return;
}
if (this.registerData && this.registerData.data && this.registerData.data.group) {
this.ins = new WebSocket(this.wsUrl);
this.onOpen();
this.received();
this.onClose();
this.onError();
}
}
/**
* 销毁当前通信
*/
;
_proto.destroy = function destroy() {
this.reconnectionLimit = 0; // 停止重连中的延时任务
clearTimeout(this.reconnectId);
this.reconnectId = undefined; // 停止还在进行轮询的心跳检测任务
clearInterval(this.hbId);
this.hbId = undefined;
clearTimeout(this.hbId_s);
this.hbId_s = undefined;
this.hearting = undefined;
window.removeEventListener('ws_load', this.loadCb);
this.loadCb = undefined;
this.ins && this.ins.close();
this.ins = undefined;
}
/**
* 心跳逻辑
*/
;
_proto.initHeartbeat = function initHeartbeat() {
var _this = this;
if (!this.hbId && !this.hearting) {
this.hbId = setInterval(function () {
_this.heartbeatDelay -= 1000;
if (!_this.hbId_s && _this.heartbeatDelay <= 0) {
_this.send(_extends({}, _this.registerData || {
data: {}
}, {
event: 'heartbeat'
})); // 开始发送心跳检测数据
_this.hearting = true;
_this.hbId_s = setTimeout(function () {
if (_this.hearting) {
_this.hearting = false;
_this.init();
clearInterval(_this.hbId);
_this.hbId = undefined;
}
clearTimeout(_this.hbId_s);
_this.hbId_s = undefined;
}, _this.options.heartbeatWait);
}
}, 1000);
}
}
/**
* 发送消息
* @param data 消息内容
*/
;
_proto.send = function send(data) {
this.ins && this.ins.send(JSON.stringify(data));
}
/**
* 当前端通信注册
* @param data 注册内容
*/
;
_proto.register = function register(data) {
if (data) {
this.registerData = data;
}
this.ins && this.ins.send(JSON.stringify(this.registerData));
}
/**
* 更新配置后重新初始化
* @param url 服务地址
* @param opts 配置
*/
;
_proto.updateOptRetry = function updateOptRetry(url, opts) {
if (url && typeof url === 'object') {
this.options = merge(this.options, url);
} else if (url && typeof url === 'string') {
this.wsUrl = url;
if (opts && typeof opts === 'object') {
this.options = merge(this.options, opts);
}
}
this.init();
};
_proto.onOpen = function onOpen() {
var _this2 = this;
if (this.ins) {
this.ins.onopen = function () {
_this2.reconnectionLimit = _this2.options.reconnectionLimit;
_this2.register();
window.dispatchEvent(new Event('ws_load')); // 心跳检测初始化
if (!_this2.options.closeHeartbeat) {
_this2.initHeartbeat();
}
};
}
};
_proto.on = function on(event, cb) {
this.loadCb = function () {
cb && cb();
};
window.addEventListener("ws_" + event, this.loadCb);
};
_proto.received = function received() {
var _this3 = this;
if (this.ins) {
this.ins.onmessage = function (e) {
try {
var _data$data;
var _data = JSON.parse(e.data); // 有同频道的端注册成功,不需要感知
if ((_data === null || _data === void 0 ? void 0 : (_data$data = _data.data) === null || _data$data === void 0 ? void 0 : _data$data.data) === 'ok') return; // 每次收到消息都重置心跳重连时间
_this3.heartbeatDelay = _this3.options.heartbeatDelay;
if (_data.event === 'heartbeat') {
_this3.hearting = false;
return;
}
var callback = _this3.options.callback; // 回调消息内容
if (callback && typeof callback === 'function') {
callback(_data);
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
}
};
}
};
_proto.onError = function onError() {
if (this.ins) {
this.ins.onerror = function (error) {
// eslint-disable-next-line no-console
console.error(error);
};
}
};
_proto.onClose = function onClose() {
var _this4 = this;
if (this.ins) {
this.ins.onclose = function () {
if (_this4.options.connectByClose && _this4.reconnectionLimit > 0) {
// 断开重连
!_this4.reconnectId && (_this4.reconnectId = setTimeout(function () {
_this4.init();
clearTimeout(_this4.reconnectId);
_this4.reconnectId = undefined;
_this4.reconnectionLimit--;
}, _this4.options.reconnectionDelay));
}
};
}
};
return Ws;
}();