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;