@midwayjs/rabbitmq
Version:
Midway Framework for rabbitmq
162 lines • 6.32 kB
JavaScript
"use strict";
/**
* This RabbitMQ Server changed from https://github.com/JeniTurtle/egg-rabbitmq-plus/blob/master/rabbitmq.ts
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RabbitMQServer = void 0;
const amqp = require("amqp-connection-manager");
const events_1 = require("events");
class RabbitMQServer extends events_1.EventEmitter {
channelManagerSet = new Set();
connection = null;
logger;
traceService;
traceEnabled;
traceInjector;
reconnectTime;
constructor(options = {}) {
super();
this.logger = options.logger;
this.traceService = options.traceService;
this.traceEnabled = options.traceEnabled ?? options?.tracing?.enable;
this.traceInjector = options.traceInjector ?? options?.tracing?.injector;
this.reconnectTime = options.reconnectTime ?? 10 * 1000;
this.bindError();
}
bindError() {
this.on('error', err => {
this.logger.error(err);
});
}
createChannel(isConfirmChannel = false) {
if (!isConfirmChannel) {
return this.connection.connection.createChannel().then(channel => {
this.bindTraceContext(channel);
return channel;
});
}
else {
return this.connection.connection.createConfirmChannel().then(channel => {
this.bindTraceContext(channel);
return channel;
});
}
}
bindTraceContext(channel) {
if (!channel || !this.traceService) {
return;
}
const injectHeaders = (options, custom) => {
const nextOptions = options ?? {};
const configuredCarrier = typeof this.traceInjector === 'function'
? this.traceInjector({
request: nextOptions,
custom,
})
: undefined;
nextOptions.headers = configuredCarrier ?? nextOptions.headers ?? {};
if (this.traceEnabled !== false) {
this.traceService.injectContext(nextOptions.headers);
}
return nextOptions;
};
if (typeof channel.sendToQueue === 'function') {
const rawSendToQueue = channel.sendToQueue.bind(channel);
channel.sendToQueue = (queue, content, options) => {
return rawSendToQueue(queue, content, injectHeaders(options, {
method: 'sendToQueue',
queue,
}));
};
}
if (typeof channel.publish === 'function') {
const rawPublish = channel.publish.bind(channel);
channel.publish = (exchange, routingKey, content, options) => {
return rawPublish(exchange, routingKey, content, injectHeaders(options, {
method: 'publish',
exchange,
routingKey,
}));
};
}
}
async connect(url, socketOptions) {
this.connection = await amqp.connect(url, socketOptions);
// 监听在设置创建 channel 的错误
this.connection.on('error', err => {
if (err) {
if (err.err) {
err = err.err;
}
this.logger.error('Message Queue error', err);
}
else {
this.logger.info('Message Queue disconnected!');
}
});
await new Promise((resolve, reject) => {
// 监听 成功连接 的通知
this.connection.on('connect', () => {
this.logger.info('Message Queue connected!');
resolve();
});
// 监听 连接失败的错误 通知
this.connection.on('connectFailed', err => {
if (err) {
if (err.err) {
err = err.err;
}
this.logger.error('Message Queue disconnected', err);
}
else {
this.logger.info('Message Queue disconnected!');
}
reject(err);
});
});
}
async createConsumer(listenerOptions, listenerCallback) {
const channelWrapper = this.connection.createChannel({
setup: (channel) => {
// `channel` here is a regular amqplib `ConfirmChannel`.
const channelHandlers = [];
// create queue
channelHandlers.push(channel.assertQueue(listenerOptions.queueName, Object.assign({ durable: true }, listenerOptions)));
if (listenerOptions.exchange) {
// create exchange
channelHandlers.push(channel.assertExchange(listenerOptions.exchange, listenerOptions.exchangeOptions?.type ?? 'topic', listenerOptions.exchangeOptions));
// bind exchange and queue
channelHandlers.push(channel.bindQueue(listenerOptions.queueName, listenerOptions.exchange, listenerOptions.routingKey || listenerOptions.pattern, listenerOptions.exchangeOptions));
}
channelHandlers.push(channel.prefetch(listenerOptions.prefetch ?? 1));
// listen queue
channelHandlers.push(channel.consume(listenerOptions.queueName, async (msg) => {
await listenerCallback(msg, channel, channelWrapper);
}, listenerOptions.consumeOptions));
return Promise.all(channelHandlers);
},
json: true,
});
return channelWrapper.waitForConnect();
}
async closeConnection() {
try {
if (this.connection) {
await this.connection.close();
}
this.logger.debug('Message Queue connection close success');
}
catch (err) {
this.logger.error('Message Queue connection close error', err);
}
finally {
this.connection = null;
}
}
async close() {
this.logger.debug('Message Queue will be close');
await this.closeConnection();
}
}
exports.RabbitMQServer = RabbitMQServer;
//# sourceMappingURL=mq.js.map