nicecode-v2/packages/biz/lib/useSocket/ws.js
2024-01-16 11:44:26 +08:00

225 lines
8.0 KiB
JavaScript

var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/useSocket/ws.ts
var ws_exports = {};
__export(ws_exports, {
default: () => ws_default
});
module.exports = __toCommonJS(ws_exports);
var import_uuid = require("uuid");
var import_func = require("@zhst/func");
var import_socket = __toESM(require("socket.io-client"));
var import_constants = require("@common/constants");
var EMITSTATE = {
NOT_CONNECT: 0,
WAITING: 1,
CONNECT: 2
};
var initRetryTime = 0;
var intervalTime = 5 * 1e3;
var maxIntervalTime = 1 * 60 * 60 * 1e3;
var Channel = class {
constructor() {
/**
* 已存在的订阅列表
*/
this.listeners = [
// {
// topic: "",
// req: "",
// suInfo: {},
// hasEmit: false,//是否已经订阅
// lastRetryInterval: 0,
// handles: {
// }
// }
];
/**
* 调试信息 记录订阅/反订阅次数
*/
this.subscribeListenerId = [];
this.unSubscribeListenerId = [];
this.init = () => {
const ioIns = this.ioIns = (0, import_socket.default)(import_constants.SOCKET_HOST, {
reconnection: true,
transports: ["websocket"],
forceNew: true
});
ioIns.on("connect", (...arg) => {
console.debug("connect", arg);
this.ioIns = ioIns;
this.listeners.forEach((v) => {
this.doEmit(v["topic"], v["req"], v["id"]);
});
});
ioIns.on("event", (...arg) => {
console.debug("event", arg);
});
ioIns.on("disconnect", (...arg) => {
console.debug("disconnect", arg);
this.subscribeListenerId = [];
this.unSubscribeListenerId = [];
});
ioIns.on("reconnect", (...arg) => {
console.debug("reconnect", arg);
this.listeners.forEach((v) => {
v["hasEmit"] = EMITSTATE.NOT_CONNECT;
this.doEmit(v["topic"], v["req"], v["id"]);
});
});
};
this.retry = (listener) => {
const intervalId = setTimeout(() => {
const hasExit = this.listeners.find(
(v) => v["topic"] === (listener == null ? 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;
};
this.doEmit = (topic, req, listenerId) => {
var _a, _b;
if (!this.ioIns) {
this.init();
}
const hasEmit = this.listeners.find(
(v) => v["topic"] === topic && v["req"] === req && v["hasEmit"] !== EMITSTATE.NOT_CONNECT
);
if (hasEmit) {
return;
}
const listener = this.listeners.find((v) => v["topic"] === topic && v["req"] === req);
listener["hasEmit"] = EMITSTATE.WAITING;
(_b = (_a = this.ioIns) == null ? void 0 : _a.emit) == null ? void 0 : _b.call(_a, topic, req, (data) => {
var _a2, _b2;
console.info("emit", topic, req, data);
const suInfo = JSON.parse(data);
if ((0, import_func.has)(suInfo, "Error.code")) {
if (suInfo.Error.code === 500) {
this.retry(listener);
}
return;
}
this.subscribeListenerId.push(listenerId);
const currentTopicIndex = this.listeners.findIndex(
(v) => v["topic"] === topic && v["req"] === req && v["id"] === listenerId
);
if (currentTopicIndex == -1) {
this.ioIns.emit("UnSubscribe", JSON.stringify(suInfo), (data2) => {
this.unSubscribeListenerId.push(listenerId);
console.debug("UNSUBSCRIBE", listenerId, topic, req, data2);
});
return;
}
if (!suInfo["SubscribeID"]) {
this.listeners.splice(currentTopicIndex, 0);
} else {
this.listeners[currentTopicIndex]["suInfo"] = suInfo;
this.listeners[currentTopicIndex]["hasEmit"] = EMITSTATE.CONNECT;
}
(_b2 = (_a2 = this.ioIns) == null ? void 0 : _a2.on) == null ? void 0 : _b2.call(_a2, suInfo["SubscribeID"], (data2) => {
console.info("on", suInfo["SubscribeID"], data2);
try {
const socketData = JSON.parse(data2);
if ((0, import_func.has)(socketData, "Error.code")) {
if (socketData.Error.code === 500) {
this.retry(listener);
}
return;
}
const { handles = {} } = this.listeners.find((v) => v["topic"] === topic && v["req"] === req) || {};
Object.keys(handles).forEach((key) => {
try {
const func = handles[key];
if (!func)
return;
func(socketData);
} catch (error) {
console.error(error);
}
});
} catch (error) {
console.debug("error", error);
}
});
});
};
}
subscribe(topic, req, handle) {
const handleId = (0, import_uuid.v4)();
const listenerId = (0, import_uuid.v4)();
const listener = this.listeners.find((v) => v["topic"] === topic && v["req"] === req);
if (listener) {
listener["handles"][handleId] = handle;
} else {
this.listeners.push({
topic,
req,
suInfo: {},
id: listenerId,
hasEmit: EMITSTATE.NOT_CONNECT,
lastRetryInterval: initRetryTime,
handles: {
[`${handleId}`]: handle
}
});
this.doEmit(topic, req, listenerId);
}
return this.unSubscribe.bind(this, topic, req, handleId, listenerId);
}
unSubscribe(topic, req, handleId, listenerId) {
const listener = this.listeners.find(
(v) => v["topic"] === topic && v["req"] === req && v["id"] === listenerId
);
const { handles = {}, suInfo } = listener || {};
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), (data) => {
this.unSubscribeListenerId.push(listenerId);
console.debug("UNSUBSCRIBE", listener["id"], topic, req, data);
});
}
this.listeners = this.listeners.filter((v) => !(v["topic"] === topic && v["req"] === req));
}
}
}
};
var channelIns = new Channel();
window.__channel__ = channelIns;
var ws_default = channelIns;