@ones-open/node-host
Version:
ONES Open Platform Node.js plugin host
164 lines (163 loc) • 6.51 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageHandler = exports.MessageTypes = void 0;
const long_1 = __importDefault(require("long"));
const config_1 = require("../config");
const message_pool_1 = require("../connect/message-pool");
const logger_1 = require("../logger");
const protocol_1 = require("../protocol");
const lodash_1 = require("lodash");
const node_utils_1 = require("@ones-op/node-utils");
exports.MessageTypes = {
Control: 0,
Plugin: 1,
Resource: 2,
Ability: 3,
Heartbeat: 4,
};
class MessageHandler {
constructor(messageQueue, controlHandler, pluginHandler, abilityHandler) {
this.messageQueue = messageQueue;
this.controlHandler = controlHandler;
this.pluginHandler = pluginHandler;
this.abilityHandler = abilityHandler;
this.controlHandler.assignMessageHandler(this);
this.pluginHandler.assignMessageHandler(this);
this.abilityHandler.assignMessageHandler(this);
if (config_1.config.platform.report_log_interval > 0) {
setInterval(() => {
this.reportLog();
}, config_1.config.platform.report_log_interval * 1000);
}
}
reportLog() {
const reportMessage = (0, protocol_1.createHeartBeatPlatformMessage)();
logger_1.logger.debug(`Report Log count: ${reportMessage.Control.Report.Log.length}`);
if (reportMessage.Control.Report.Log.length <= 0) {
return;
}
this.send(exports.MessageTypes.Heartbeat, reportMessage);
}
/**
* 仅发送消息到开放平台
*/
send(msgType, message) {
const platformMessage = protocol_1.protocol.PlatformMessage.fromObject(message);
if (config_1.config.host.debug_mode) {
let logMsg = `Send Message: [SeqNo:${platformMessage.Header?.SeqNo}]`;
switch (msgType) {
case exports.MessageTypes.Control:
logMsg += JSON.stringify(platformMessage.Control);
break;
case exports.MessageTypes.Plugin:
logMsg += JSON.stringify(platformMessage.Plugin);
break;
case exports.MessageTypes.Resource:
logMsg += JSON.stringify(platformMessage.Resource);
break;
case exports.MessageTypes.Ability:
logMsg += JSON.stringify(platformMessage.Ability);
break;
case exports.MessageTypes.Heartbeat:
logMsg += `Heartbeat: ${platformMessage.Control?.Heartbeat} LogCount: ${platformMessage.Control?.Report?.Log?.length}`;
break;
}
logger_1.logger.debug(logMsg);
}
this.messageQueue.sendMessage(platformMessage).catch((err) => {
logger_1.logger.error(`Send Message Failed, [SeqNo:${platformMessage.Header?.SeqNo}]`, err);
});
}
fetch(message, timeout) {
const finalMessage = (0, lodash_1.merge)({ Header: (0, protocol_1.createHeader)() }, message);
const platformMessage = protocol_1.protocol.PlatformMessage.fromObject(finalMessage);
if (config_1.config.host.debug_mode) {
logger_1.logger.debug(`Fetch Message: [SeqNo:${platformMessage.Header?.SeqNo}] ${JSON.stringify(message)}`);
}
return this.fecthMessage(platformMessage, timeout);
}
/**
* 发送消息到开放平台(并可等待返回)
*/
fecthMessage(platformMessage, timeout) {
const seqNo = platformMessage.Header?.SeqNo;
if (!seqNo) {
throw new Error('seqNo must be required!');
}
const seqString = seqNo.toString();
return new Promise((resolve, reject) => {
let timer;
if (timeout) {
timer = setTimeout(() => {
message_pool_1.FetchMessagePool.set(seqString, null);
reject((0, node_utils_1.TimeoutError)());
}, timeout);
}
const emptyEffect = () => {
timer && clearTimeout(timer);
message_pool_1.FetchMessagePool.delete(seqString);
};
const next = (platformMessage) => {
emptyEffect();
resolve(platformMessage);
};
const onError = (error) => {
emptyEffect();
reject(new Error(`fetch error: ${error}`));
};
message_pool_1.FetchMessagePool.set(seqString, next);
this.messageQueue.sendMessage(platformMessage).catch(onError);
});
}
/**
* 处理HOST主动发送的消息的回调,如果消息已经被处理过,则返回true,否则返回false
*/
onFetchReturn(platformMessage) {
const seqNo = platformMessage.Header?.SeqNo;
const seqString = long_1.default.isLong(seqNo) ? seqNo.toString() : seqNo?.toString() ?? '';
const callback = message_pool_1.FetchMessagePool.get(seqString);
// 如果消息已经被处理过,则返回true,如:超时处理
if (callback === null) {
message_pool_1.FetchMessagePool.delete(seqString);
return true;
}
if (callback) {
callback(platformMessage);
return true;
}
return false;
}
/**
* 消息处理器对消息的处理逻辑
*/
onMessage(platformMessage) {
const message = protocol_1.protocol.PlatformMessage.toObject(platformMessage, {
enums: Number,
longs: String,
});
if (config_1.config.host.debug_mode) {
logger_1.logger.debug(`Received Message: `, message);
}
// 回调消息(触发fetch().then)
if (this.onFetchReturn(message)) {
return;
}
// 👇仅处理平台主动向HOST发的消息👇
// 控制流
if (message.Control) {
this.controlHandler.onMessage(message);
}
// 事件流
if (message.Plugin) {
this.pluginHandler.onMessage(message);
}
// notify event
if (message.Ability) {
this.abilityHandler.onMessage(message);
}
}
}
exports.MessageHandler = MessageHandler;