【问题标题】:Node RabbitMQ consume message and do something for each message节点 RabbitMQ 消费消息并为每条消息做一些事情
【发布时间】:2020-06-16 15:33:35
【问题描述】:

我想使用来自 rabbitmq 服务的消息,并且对于我收到的每条消息,我都想做一些事情(例如:将该消息放入数据库,处理消息并通过 RabbitMq 通过另一个队列发送回复)每条消息。

目前我的 RabbitMq 消费者代码如下:

const all = require('bluebird').all;
const basename = require('path').basename;


function receive() {
    const severities = process.argv.slice(2);
    if (severities.length < 1) {
        console.warn('Usage: %s [info] [warning] [error]',
            basename(process.argv[1]));
        process.exit(1);
    }
    let config = {
        protocol: 'amqp',
        hostname: 'localhost',
        port: 5672,
        username: 'rumesh',
        password: 'password',
        locale: 'en_US',
        frameMax: 0,
        heartbeat: 0,
        vhost: '/',
    };
    amqp.connect(config).then(function (conn) {
        process.once('SIGINT', function () {
            conn.close();
        });
        return conn.createChannel().then(function (ch) {
            let queue = 'test';
            let exchange = 'test-exchange';
            let key = 'python-key';
            let exchange_type = 'direct';

            let ok = ch.assertExchange(exchange, exchange_type, {durable: true});

            ok = ok.then(function () {
                return ch.assertQueue(queue, { durable: true});
            });

            ok = ok.then(function (qok) {
                const queue = qok.queue;
                return all(severities.map(function (sev) {
                    ch.bindQueue(queue, exchange, sev,{durable: true});
                })).then(function () {
                    return queue;
                });
            });

            ok = ok.then(function (queue) {
                return ch.consume(queue, logMessage, {noAck: true});
            });
            return ok.then(function () {
                console.log(' [*] Waiting for logs. To exit press CTRL+C.');
            });

            function logMessage(msg) {
                console.log(" [x] %s:'%s'",
                    msg.fields.routingKey,
                    msg.content.toString());
            }
        });
    }).catch(console.warn);
}


module.exports = receive;```

【问题讨论】:

    标签: node.js rabbitmq node-amqp node-amqplib


    【解决方案1】:

    我建议您创建一个处理函数,例如 onNewMessage,每次您在队列中收到新消息时都会调用该处理函数。

    您可以通过多种方式对消息进行编码,因为您可以通过 AMQP 发送二进制数据。

    JSON 绝对是一种发送消息的方式,这在 Node.js 中处理起来非常方便。

    这里有一些示例代码连接到服务器,然后发送和接收消息:

    const amqp = require('amqplib');
    
    const queue = 'test';
    
    // Set your config here...
    let config = {
        protocol: 'amqp',
        hostname: 'localhost',
        port: 5672,
        username: 'rumesh',
        password: 'password',
        locale: 'en_US',
        frameMax: 0,
        heartbeat: 0,
        vhost: '/',
    };
    
    
    async function start() {
        try {
            const conn = await createConnection(config);
            console.log("Connected to AMQP server.");
            let channel = await conn.createChannel();
            await channel.assertQueue(queue, { durable: true});
    
            startPollingForMessages(channel);
            startSendingMessages(channel);
        } catch (err) {
            console.error("start: Connection error:",err.message);
        }
    }
    
    async function createConnection(config) {
        const conn = await amqp.connect(config);
    
        conn.on("error", function(err) {
            console.error("Connection error:",err.message);
        });
    
        conn.on("close", function() {
            console.error("Connection closed:", err.message);
        });
    
        return conn;
    }
    
    function startSendingMessages(channel) {
        const SEND_INTERVAL = 5000;
        setInterval(() => { 
            sendMessage(channel, queue, JSON.stringify({ timestamp: new Date().toISOString(), message: " Some message" })); 
        }, SEND_INTERVAL);
    }
    
    async function sendMessage(channel, queue, messageContent) {
        console.log(`sendMessage: sending message: ${messageContent}...`);
        return channel.sendToQueue(queue, Buffer.from(messageContent))
    }
    
    function startPollingForMessages(ch) {
        ch.consume(queue, (msg) => {
            onNewMessage(msg);
            ch.ack(msg);
        });
    }
    
    function onNewMessage(msg) {
        // Do your database stuff or whatever here....
        console.log("On new message:", msg.content.toString())
    }
    
    start();
    

    【讨论】:

    • 你好,如果我想接收消息,代码应该如何组织,然后处理它(保存到数据库)并发送响应?因为据我了解,提供的代码会发送一条消息并接收它吗? (我是 nodeJS 的初学者)
    • 您将确保仅在消息安全存储到数据库后才确认消息,因此 onNewMessage 最有可能返回 Promise(或接受回调作为参数),因此我们只会确认成功写入的消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-08
    • 2016-11-13
    • 2021-07-28
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    相关资源
    最近更新 更多