【问题标题】:RabbitMQ amqp.node integration with nodejs expressRabbitMQ amqp.node 与 nodejs express 集成
【发布时间】:2017-01-07 13:11:32
【问题描述】:

官方 RabbitMQ Javascript 教程展示了 amqp.node 客户端库的用法

amqp.connect('amqp://localhost', function(err, conn) {
  conn.createChannel(function(err, ch) {
    var q = 'hello';

    ch.assertQueue(q, {durable: false});
    // Note: on Node 6 Buffer.from(msg) should be used
    ch.sendToQueue(q, new Buffer('Hello World!'));
    console.log(" [x] Sent 'Hello World!'");
  });
});

但是,我发现很难在其他地方重用此代码。特别是,我不知道如何导出通道对象,因为它在回调中。例如在我的 NodeJs/Express 应用程序中:

app.post('/posts', (req, res) => {
    -- Create a new Post
    -- Publish a message saying that a new Post has been created
    -- Another 'newsfeed' server consume that message and update the newsfeed table
    // How do I reuse the channel 'ch' object from amqp.node here
});

你们有这方面的指导吗?欢迎其他库的建议(因为我刚开始,易用性是我认为最重要的)

【问题讨论】:

  • 如果需要导出频道对象,可以在创建频道的文件中使用module.exports。例如在conn.createChannel 回调中调用module.exports.channel = ch。然后,您可以从“需要”通道创建脚本的不同文件中访问它,如下所示:channelCreatingScript.channel.
  • 它将开始未定义
  • 您可以将 export 语句放在外面 - 并为其分配 null{}。当您通过module.exports.channel 分配新值时,它会更新它。
  • 是否强制仅在创建通道后进行导出?
  • 这种情况下你只需要在回调中做,然后当你使用它时,一定要检查undefined TypeErrors。试一试,让我知道。我在下面的答案中写了一个示例代码。

标签: javascript node.js express rabbitmq amqp


【解决方案1】:

amqp.node 是一个低级 API 集,可以将 AMQP 到 Node.js 的转换降至最低。它基本上是一个应该从更友好的 API 使用的驱动程序。

如果您想要一个 DIY 解决方案,请创建一个 API,您可以从您的模块中导出该 API,并在该 API 文件中管理连接、通道和其他对象。

但我不建议自己做。把事情做好并不容易。

我建议使用像 Rabbot (https://github.com/arobson/rabbot/) 这样的库来为您处理这个问题。

我使用 Rabbot 已经有一段时间了,我真的很喜欢它的工作方式。它将 AMQP 的细节推到一边,让我专注于我的应用程序的业务价值和构建功能所需的消息传递模式。

【讨论】:

    【解决方案2】:

    如 cmets 中所述,您可以使用 module.exports 公开新创建的通道。当然,每次创建新通道时都会覆盖这一点,除非您想保留通道数组或其他数据结构。 假设这是在一个名为 channelCreator.js 的脚本中:

    amqp.connect('amqp://localhost', function(err, conn) {
      conn.createChannel(function(err, ch) {
        var q = 'hello';
    
        ch.assertQueue(q, {durable: false});
        //this is where you can export the channel object
        module.exports.channel = ch;  
        //moved the sending-code to some 'external script'
      });
    });
    

    在您可能想要使用“导出”通道的脚本中:

        var channelCreator = require("<path>/channelCreator.js");
        //this is where you can access the channel object:
        if(channelCreator.channel){
          channelCreator.channel.sendToQueue('QueueName', new Buffer('This is Some Message.'));
          console.log(" [x] Sent 'Message'");
        }
    

    希望这会有所帮助。

    【讨论】:

    • 如果 channelCreator.channel 未定义怎么办?我不能只是放弃我的消息,对吧?可能的情况是我等待它被初始化,但我真的不知道它什么时候会
    • 非常感谢您的帮助,我的朋友。我真的很感谢你花时间和我在一起:D
    • 乐于助人。在您想等到创建通道的情况下,我真的认为您需要使用回调函数,就像amqplib 示例所示。
    • 虽然这在技术上可行,但它会给您的代码带来竞争条件和大问题。你不应该从回调内部调用module.exports
    • 我最终编写了自己的包含 amqplib 的库:github.com/rocketspacer/ezamqpliblol xD
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 2019-08-16
    • 2023-03-26
    • 1970-01-01
    • 2012-05-08
    相关资源
    最近更新 更多