244 lines
10 KiB
JavaScript
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; |