const amqp = require('amqplib');
const { mqCfg } = require('../config')
const Base = require('../core/Base')
//单例复用tcp连接
let connect;
let queue = "queue" //默认队列名称
const attr = { autoDelete: false, durable: true }
//autoDelete 断开清空队列 durable 硬盘持久化
class AMQP {
static async getConnection() {
try {
if (!connect) {
console.log('~~~~开始新连接~~~~')
connect = await amqp.connect(mqCfg.mq1,
{
clientProperties: {
connection_name: `大查柜-${Base.now()}`
}
})
connect.on("error", (err) => {
connect = null //清空失败连接
console.log(`[×] RabbitMQ 异常断线 ${Base.now()}`);
});
connect.on("close", () => {
connect = null
console.log(`[×] RabbitMQ 异常断线 ${Base.now()}`);
});
console.log(`[√] RabbitMQ 连接成功 ${Base.now()}`);
}
return connect
} catch (err) {
console.log(`[×] RabbitMQ 连接错误 ${Base.now()}` + err.message)
}
}
/**
* 获取普通队列,发布者,订阅消费者可用
* @param queue
* @param queueAttr
* @returns {Promise<void>}
*/
static async getQueue(queue = queue, queueAttr = attr) {
let conn = await this.getConnection()
let ch = await connect.createChannel()
//初始化队列
await ch.assertQueue(queue, queueAttr);
return ch
}
/**
* 发布消息到队列
* @param queue
* @param msg
* @returns {Promise<void>}
*/
static async publishMsg(queue, msg) {
const channel = await this.getQueue(queue)
console.log(msg)
msg = Buffer.from(JSON.stringify(msg));
let rs = await channel.sendToQueue(queue, msg, { persistent: true })
channel.close()
return rs
}
static async subs(queue, cb) {
const ch = await this.getQueue(queue)
ch.prefetch(1)
ch.on("close", async (err) => {
connect = null
console.log(`[×] RabbitMQ channel异常断开 ${Base.now()}`);
setTimeout(() => { AMQP.subs(queue, cb) }, 1000)
})
await ch.consume(queue, (msg) => {
console.log(`消费消息: %s ${Base.now()}`, msg.content.toString());
cb(msg, ch)
})
}
/**
* 订阅队列消费
* @param queue
* @param cb callback 回调处理函数
* @returns {Promise<void>}
*/
static async subscribe(queue) {
const ch = await this.getQueue(queue)
ch.prefetch(1)
ch.on("close", (err) => {
// connect = null
console.log("ch异常中断:" + err);
setTimeout(async () => {
console.log("ch重连")
connect = null
await this.subscribe(queue, cb)
}, 3000);
});
// channel.ack(message);n
await ch.consume(queue, (msg) => {
// console.log('Return data: %s', msg.content.toString());
try {
this.echo(msg.content.toString());
ch.ack(msg);
}catch (e) {
ch.nack(msg); //处理失败塞回队列顶部
}
})
// console.log('consume...')
// channel.close();
// ch.consume(q.queue, function (msg) {
// if (msg.properties.correlationId === corr) {
// console.log('Return data: %s', msg.content.toString());
// // Feature 返回的数据不要处理,交回给 Api 处理
// callback(msg.content.toString())
// }
// }, {noAck: true});
// function(message)
// {
// console.log(message.content.toString());
// channel.ack(message);
// });
}
static async echo(msg){
msg = JSON.parse(msg);
console.log(msg.name)
}
}
module.exports = AMQP;
// console.log(AMQP.publishMsg(queue,{"name":"qql"}))
// console.log(AMQP.subscribe(queue))
config.js 文件
mqCfg: { //rabbitMQ
mq1: {
protocol: 'amqp',
hostname: '127.0.0.1',
port: 5672,
username: 'qql',
password: '123456',
locale: 'zh_CN',
frameMax: 0,
heartbeat: 0,
vhost: 'message'
}
},