无法通过RabbitMQ消息发布选项吗?

问题描述 投票:1回答:2

我在节点代码中使用ampq.node进行RabbitMQ访问。我正在尝试使用publishsendToQueue方法,通过options参数在发布的消息中包含一些元数据(即时间戳和内容类型)。

但是我传递给options的任何内容都将被完全忽略。我想我缺少一些格式或字段名称,但是我找不到任何可靠的文档(除了提供的here似乎无法完成工作)。

下面是我的publish功能代码:

  var publish = function(queueName, message) {
    let content;
    let options = {
      persistent: true,
      noAck: false,
      timestamp: Date.now(),
      contentEncoding: 'utf-8'
    };
    if(typeof message === 'object') {
      content = new Buffer(JSON.stringify(message));
      options.contentType = 'application/json';
    }
    else if(typeof message === 'string') {
      content = new Buffer(message);
      options.contentType = 'text/plain';
    }
    else {  //message is already a buffer?
      content = message;
    }
    return Channel.sendToQueue(queueName, content, options); //Channel defined and opened elsewhere
  };

我想念什么?

更新:事实证明,如果选择使用ConfirmChannel,则必须提供回调函数作为最后一个参数,否则将忽略options对象。因此,一旦我将代码更改为以下代码,就可以正确看到选项:

Channel.sendToQueue(queueName, content, options, (err, result) => {...});

node.js queue rabbitmq
2个回答
3
投票

不知何故,我似乎无法发布您的示例……尽管我没有发现任何特别错误的地方。我不确定为什么我无法使您的示例代码正常工作。

但是我能够修改自己的amqplib简介代码的版本,并使其与您的选项配合使用就可以了。

这是我的示例的完整代码:

// test.js file

var amqplib = require("amqplib");

var server = "amqp://test:password@localhost/test-app";

var connection, channel;

function reportError(err){
  console.log("Error happened!! OH NOES!!!!");
  console.log(err.stack);
  process.exit(1);
}

function createChannel(conn){
  console.log("creating channel");
  connection = conn;
  return connection.createChannel();
}

function sendMessage(ch){
  channel = ch;

  console.log("sending message");
  var msg = process.argv[2];
  var message = new Buffer(msg);

  var options = {
    persistent: true,
    noAck: false,
    timestamp: Date.now(),
    contentEncoding: "utf-8",
    contentType: "text/plain"
  };

  channel.sendToQueue("test.q", message, options);
  return channel.close();
}

console.log("connecting");
amqplib.connect(server)
  .then(createChannel)
  .then(sendMessage)
  .then(process.exit, reportError);

要运行此命令,请打开命令行并执行:

node test.js "example text message"

运行后,您会在“ test-app”虚拟主机中看到消息显示在“ test.q”队列中(假设您已创建该队列)。

这里是RMQ管理插件产生的消息的屏幕截图:

message from rmq server


旁注:

我建议不要使用sendToQueue。正如我在RabbitMQ Patterns email course / ebook中说的:

我花了一段时间才意识到这一点,但现在我将RabbitMQ的“发送到队列”功能作为反模式。

当然,它已内置在库和协议中。而且很方便,对吗?但这并不意味着您应该使用它。这是使演示变得简单并可以处理某些特定情况的功能之一。但一般来说,“发送到队列”是一种反模式。

[当您是消息产生者时,您只关心使用正确的路由密钥将消息发送到正确的交换机。当您是消息使用者时,您会关心消息目的地-您预订的队列。每天可以使用同一路由密钥将消息发送到同一交换机,每天每天数千次。但是,这并不意味着它将每次都到达相同的队列。

随着消息使用者上线和下线,他们可以创建新的队列和绑定并删除旧的队列和绑定。消息生产者和消费者的这种观点告诉了队列的性质:可以在需要时改变的邮政信箱。

我也建议不要直接使用amqplib。这是一个很棒的库,但是缺乏很多可用性。而是在amqplib顶部寻找一个好的库。

我更喜欢wascally, by LeanKit。它是基于amqplib的抽象要容易得多,并且提供了许多出色的功能。

最后,如果您在启动RMQ并与Node.js一起运行,设计与之配合使用的应用等方面苦于其他细节,请查看我的RabbitMQ For Devs课程-它从零到英雄,快速。 :)


0
投票

这可能会对其他人有所帮助,但是用于内容类型的键名称在JavaScript代码中为contentType。使用Rabbit MQ的Web Gui,他们使用content_type作为键名。不同的键名来声明选项,因此请确保在正确的上下文中使用正确的键名。

© www.soinside.com 2019 - 2024. All rights reserved.