UNPKG

ts-api-core

Version:

Nodejs api framework core

247 lines 11.6 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RabbitMQAccess = exports.RabbitMQConfig = void 0; const utils_1 = require("../utils"); const ioc_decorator_1 = require("../../mvc/ioc.decorator"); const package_loader_1 = require("../package.loader"); /** RabbitMQ 配置 */ class RabbitMQConfig { } exports.RabbitMQConfig = RabbitMQConfig; /** * RabbitMQ Client Access */ let RabbitMQAccess = class RabbitMQAccess extends ioc_decorator_1.BaseProvider { constructor(config) { super(); this.config = config; } onFree() { void this.relase(); } get amqplib() { if (!this._amqplib) { this._amqplib = package_loader_1.PackageLoader.load('amqplib'); } return this._amqplib; } consume(onRecvMsg, routeKey, config) { if (config) { this.config = config; } this.routeKey = routeKey; this.onRecvMsg = onRecvMsg !== null && onRecvMsg !== void 0 ? onRecvMsg : this.onRecvMsg; if (!this.onRecvMsg) { throw new Error('必须指定 onRecvMsg 实现'); } console.log(utils_1.Utils.getNowString(), '启动 RabbitMQ 消息处理服务'); this.startRecvServer(routeKey !== null && routeKey !== void 0 ? routeKey : this.config.routeKey).catch(err => { console.log(utils_1.Utils.getNowString(), 'RabbitMQ 消息处理服务错误:', err.message, '正在重启'); this.reStartRecv(); }); } send(msg, args) { return __awaiter(this, void 0, void 0, function* () { return this.sendMsg({ data: msg, args }, args); }); } sendMsg(msg, args) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { try { if (!this.sendChannel) { yield this.relaseSendConn(); this.sendConnection = yield this.getConnection(this.config, (err) => { console.error(utils_1.Utils.getNowString(), 'RabbitMQ 遇到连接错误:', err.message); if (this.sendConnection) { utils_1.Utils.executeSilence(this.sendConnection.close()); this.sendConnection = undefined; } if (this.sendChannel) { utils_1.Utils.executeSilence(this.sendChannel.close()); this.sendChannel = undefined; } }); this.sendChannel = yield this.sendConnection.createChannel(); yield this.initChannelExchange(this.sendChannel); } const buff = Buffer.from(JSON.stringify(msg)); const _args = Object.assign({ persistent: true, mandatory: true }, args !== null && args !== void 0 ? args : {}); this.sendChannel.publish(this.config.exchangeName, (_a = this.config.sendRouteKey) !== null && _a !== void 0 ? _a : "", buff, _args); } catch (e) { try { yield ((_b = this.sendChannel) === null || _b === void 0 ? void 0 : _b.close()); } catch (e1) { } this.sendChannel = undefined; console.log('RabbitMQ 发送消息失败: ' + e.toString()); } }); } startRecvServer(routeKey) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { yield this.relaseRecvConn(); this.recvConnection = (_a = this.recvConnection) !== null && _a !== void 0 ? _a : yield this.getConnection(this.config, (err) => { console.error(utils_1.Utils.getNowString(), 'RabbitMQ 遇到连接错误:', err.message, '准备重启'); this.reStartRecv(); }); this.receiveChannel = yield this.assertChannel(this.recvConnection); const retryCount = (_b = this.config.retryCount) !== null && _b !== void 0 ? _b : 0; const needRetry = retryCount !== undefined && retryCount > 0; yield this.initialChannel(this.receiveChannel, routeKey); yield this.receiveChannel.consume(this.config.queueName, (msg) => { if (!msg || !this.receiveChannel) { return; } const channel = this.receiveChannel; let data = JSON.parse(msg.content.toString()); this.onRecvMsg(data.data).then((isOK) => { if (isOK) { channel.ack(msg); } else if (!needRetry) { channel.nack(msg, false, false); } else { if (!data.__retryRef) { data.__retryRef = 1; } else { data.__retryRef++; } if (data.__retryRef <= retryCount) { channel.ack(msg); this.sendMsg(data, data.args); } else { channel.nack(msg, false, false); } } }).catch((err) => { var _a; console.log('RabbitMQ 消息处理错误:', data.data, err.message); channel.nack(msg, false, (_a = this.config.faildRequeue) !== null && _a !== void 0 ? _a : true); }); }, this.config.consumeOptions); console.log(utils_1.Utils.getNowString(), 'RabbitMQ 服务启动成功,开始接收消息'); }); } relase() { return __awaiter(this, void 0, void 0, function* () { yield this.relaseSendConn(); yield this.relaseRecvConn(); }); } relaseRecvConn() { return __awaiter(this, void 0, void 0, function* () { if (this.recvConnection) { yield utils_1.Utils.executeSilence(this.recvConnection.close()); this.recvConnection = undefined; } if (this.receiveChannel) { yield utils_1.Utils.executeSilence(this.receiveChannel.close()); this.receiveChannel = undefined; } }); } relaseSendConn() { return __awaiter(this, void 0, void 0, function* () { if (this.sendConnection) { yield utils_1.Utils.executeSilence(this.sendConnection.close()); this.sendConnection = undefined; } if (this.sendChannel) { yield utils_1.Utils.executeSilence(this.sendChannel.close()); this.sendChannel = undefined; } }); } getConnection(config, onError) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const connect = this.amqplib.connect; let connection = yield connect({ hostname: config.host, port: (_a = config.port) !== null && _a !== void 0 ? _a : 5672, username: config.username, password: config.password, vhost: config.virtualHost, heartbeat: (_b = config.heartbeat) !== null && _b !== void 0 ? _b : 10, locale: config.locale, protocol: config.protocol }); if (!connection) { throw new Error('RabbitMQ 连接初始化失败'); } connection.on('error', (err) => { if (onError) { onError(err); } }); return connection; }); } reStartRecv() { setTimeout(() => { this.consume(undefined, this.routeKey); }, 1000); } assertChannel(connection) { var _a; return __awaiter(this, void 0, void 0, function* () { let channel = yield connection.createChannel(); // 设置客户端一次只能处理一条消息 yield channel.prefetch((_a = this.config.prefetch) !== null && _a !== void 0 ? _a : 1); return channel; }); } assertQueue(channel, queueName, exclusive) { return __awaiter(this, void 0, void 0, function* () { return yield channel.assertQueue(queueName, exclusive ? { exclusive: true } : undefined); }); } initialChannel(channel, routeKey) { return __awaiter(this, void 0, void 0, function* () { const queue = yield this.assertQueue(channel, this.config.queueName, this.config.exclusive); yield this.initChannelExchange(channel); if (this.config.exchangeName && routeKey) { yield channel.bindQueue(queue.queue, this.config.exchangeName, routeKey); } }); } initChannelExchange(channel) { var _a; return __awaiter(this, void 0, void 0, function* () { if (this.config.exchangeName) { // 定义交换机 和设置交换机的模型 const exchangeType = this.config.exchangeType ? this.config.exchangeType : 'topic'; const exchangeArgs = Object.assign({ durable: true, autoDelete: false }, (_a = this.config.exchangeArgs) !== null && _a !== void 0 ? _a : {}); yield channel.assertExchange(this.config.exchangeName, exchangeType, exchangeArgs); } }); } }; RabbitMQAccess = __decorate([ (0, ioc_decorator_1.Provide)(), __metadata("design:paramtypes", [RabbitMQConfig]) ], RabbitMQAccess); exports.RabbitMQAccess = RabbitMQAccess; //# sourceMappingURL=rabbitmq.access.js.map