node.js 使用rabbitmq

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}
     */
    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}
     */
    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}
     */
    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'
        }
    },

 

你可能感兴趣的:(node.js)