ts-api-core
Version:
Nodejs api framework core
247 lines • 11.6 kB
JavaScript
"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