nicecode-v2/packages/biz/es/useSocket/ws.js

244 lines
10 KiB
JavaScript

function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
// @ts-nocheck
import { v4 as uuidv4 } from 'uuid';
import { has } from '@zhst/func';
import io from 'socket.io-client';
import { SOCKET_HOST } from '@common/constants';
var EMITSTATE = {
NOT_CONNECT: 0,
WAITING: 1,
CONNECT: 2
};
var initRetryTime = 0;
var intervalTime = 5 * 1000; //下次重试增加时间
var maxIntervalTime = 1 * 60 * 60 * 1000; //最大重试时间1小时
var Channel = /*#__PURE__*/function () {
function Channel() {
var _this = this;
_classCallCheck(this, Channel);
/**
* io 实例化对象
*/
_defineProperty(this, "ioIns", void 0);
/**
* 已存在的订阅列表
*/
_defineProperty(this, "listeners", [
// {
// topic: "",
// req: "",
// suInfo: {},
// hasEmit: false,//是否已经订阅
// lastRetryInterval: 0,
// handles: {
// }
// }
]);
/**
* 调试信息 记录订阅/反订阅次数
*/
_defineProperty(this, "subscribeListenerId", []);
_defineProperty(this, "unSubscribeListenerId", []);
_defineProperty(this, "init", function () {
var ioIns = _this.ioIns = io(SOCKET_HOST, {
reconnection: true,
transports: ['websocket'],
forceNew: true
});
ioIns.on('connect', function () {
for (var _len = arguments.length, arg = new Array(_len), _key = 0; _key < _len; _key++) {
arg[_key] = arguments[_key];
}
console.debug('connect', arg);
_this.ioIns = ioIns;
_this.listeners.forEach(function (v) {
_this.doEmit(v['topic'], v['req'], v['id']);
});
});
ioIns.on('event', function () {
for (var _len2 = arguments.length, arg = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
arg[_key2] = arguments[_key2];
}
console.debug('event', arg);
});
ioIns.on('disconnect', function () {
for (var _len3 = arguments.length, arg = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
arg[_key3] = arguments[_key3];
}
console.debug('disconnect', arg);
_this.subscribeListenerId = [];
_this.unSubscribeListenerId = [];
});
ioIns.on('reconnect', function () {
for (var _len4 = arguments.length, arg = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
arg[_key4] = arguments[_key4];
}
console.debug('reconnect', arg);
_this.listeners.forEach(function (v) {
v['hasEmit'] = EMITSTATE.NOT_CONNECT;
_this.doEmit(v['topic'], v['req'], v['id']);
});
});
});
_defineProperty(this, "retry", function (listener) {
//重试逻辑
var intervalId = setTimeout(function () {
var hasExit = _this.listeners.find(function (v) {
return v['topic'] === (listener === null || listener === void 0 ? void 0 : listener['topic']) && v['req'] === listener['req'];
});
if (!hasExit) return;
listener['hasEmit'] = EMITSTATE.NOT_CONNECT;
_this.doEmit(listener['topic'], listener['req'], listener['id']);
}, listener.lastRetryInterval);
listener.intervalId = intervalId;
listener.lastRetryInterval = intervalTime + listener.lastRetryInterval > maxIntervalTime ? maxIntervalTime : intervalTime + listener.lastRetryInterval;
});
_defineProperty(this, "doEmit", function (topic, req, listenerId) {
var _this$ioIns, _this$ioIns$emit;
if (!_this.ioIns) {
_this.init();
}
//订阅过就不订阅了
var hasEmit = _this.listeners.find(function (v) {
return v['topic'] === topic && v['req'] === req && v['hasEmit'] !== EMITSTATE.NOT_CONNECT;
});
if (hasEmit) {
return;
}
var listener = _this.listeners.find(function (v) {
return v['topic'] === topic && v['req'] === req;
});
listener['hasEmit'] = EMITSTATE.WAITING;
(_this$ioIns = _this.ioIns) === null || _this$ioIns === void 0 || (_this$ioIns$emit = _this$ioIns.emit) === null || _this$ioIns$emit === void 0 || _this$ioIns$emit.call(_this$ioIns, topic, req, function (data) {
var _this$ioIns2, _this$ioIns2$on;
console.info('emit', topic, req, data);
var suInfo = JSON.parse(data);
if (has(suInfo, 'Error.code')) {
if (suInfo.Error.code === 500) {
//后端出错
_this.retry(listener);
}
return;
}
// console.debug('SUBSCRIBE', listenerId, topic, req, suInfo);
_this.subscribeListenerId.push(listenerId);
// debugger
//重新找一遍topic
var currentTopicIndex = _this.listeners.findIndex(function (v) {
return v['topic'] === topic && v['req'] === req && v['id'] === listenerId;
});
if (currentTopicIndex == -1) {
// 不存在说明listener取消了 直接反订阅
_this.ioIns.emit('UnSubscribe', JSON.stringify(suInfo), function (data) {
_this.unSubscribeListenerId.push(listenerId);
console.debug('UNSUBSCRIBE', listenerId, topic, req, data);
});
return;
}
if (!suInfo['SubscribeID']) {
_this.listeners.splice(currentTopicIndex, 0);
} else {
_this.listeners[currentTopicIndex]['suInfo'] = suInfo;
_this.listeners[currentTopicIndex]['hasEmit'] = EMITSTATE.CONNECT;
}
(_this$ioIns2 = _this.ioIns) === null || _this$ioIns2 === void 0 || (_this$ioIns2$on = _this$ioIns2.on) === null || _this$ioIns2$on === void 0 || _this$ioIns2$on.call(_this$ioIns2, suInfo['SubscribeID'], function (data) {
console.info('on', suInfo['SubscribeID'], data);
try {
var socketData = JSON.parse(data);
if (has(socketData, 'Error.code')) {
if (socketData.Error.code === 500) {
//后端出错
_this.retry(listener);
}
return;
}
var _ref = _this.listeners.find(function (v) {
return v['topic'] === topic && v['req'] === req;
}) || {},
_ref$handles = _ref.handles,
handles = _ref$handles === void 0 ? {} : _ref$handles;
Object.keys(handles).forEach(function (key) {
try {
//后面观察 为什么delete后在foreach
var func = handles[key];
if (!func) return;
func(socketData);
} catch (error) {
console.error(error);
}
});
} catch (error) {
console.debug('error', error);
}
});
});
});
}
_createClass(Channel, [{
key: "subscribe",
value: function subscribe(topic, req, handle) {
var handleId = uuidv4();
var listenerId = uuidv4();
var listener = this.listeners.find(function (v) {
return v['topic'] === topic && v['req'] === req;
});
if (listener) {
listener['handles'][handleId] = handle;
} else {
this.listeners.push({
topic: topic,
req: req,
suInfo: {},
id: listenerId,
hasEmit: EMITSTATE.NOT_CONNECT,
lastRetryInterval: initRetryTime,
handles: _defineProperty({}, "".concat(handleId), handle)
});
//未注册过 则去订阅
this.doEmit(topic, req, listenerId);
}
return this.unSubscribe.bind(this, topic, req, handleId, listenerId);
}
}, {
key: "unSubscribe",
value: function unSubscribe(topic, req, handleId, listenerId) {
var _this2 = this;
var listener = this.listeners.find(function (v) {
return v['topic'] === topic && v['req'] === req && v['id'] === listenerId;
});
var _ref2 = listener || {},
_ref2$handles = _ref2.handles,
handles = _ref2$handles === void 0 ? {} : _ref2$handles,
suInfo = _ref2.suInfo;
if (handles[handleId]) {
delete handles[handleId];
//如果没有其他订阅就删除
if (Object.keys(handles).length === 0) {
if (this.intervalId) {
clearTimeout(this.intervalId);
}
if (listener['hasEmit'] === EMITSTATE['CONNECT']) {
this.ioIns.emit('UnSubscribe', JSON.stringify(suInfo), function (data) {
_this2.unSubscribeListenerId.push(listenerId);
console.debug('UNSUBSCRIBE', listener['id'], topic, req, data);
});
}
this.listeners = this.listeners.filter(function (v) {
return !(v['topic'] === topic && v['req'] === req);
});
}
}
}
}]);
return Channel;
}(); //单例
var channelIns = new Channel();
//暴露实例 调试用
window.__channel__ = channelIns;
export default channelIns;