我在节点代码中使用ampq.node进行RabbitMQ访问。我正在尝试使用publish
或sendToQueue
方法,通过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) => {...});
不知何故,我似乎无法发布您的示例……尽管我没有发现任何特别错误的地方。我不确定为什么我无法使您的示例代码正常工作。
但是我能够修改自己的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管理插件产生的消息的屏幕截图:
旁注:
我建议不要使用sendToQueue
。正如我在RabbitMQ Patterns email course / ebook中说的:
我花了一段时间才意识到这一点,但现在我将RabbitMQ的“发送到队列”功能作为反模式。
当然,它已内置在库和协议中。而且很方便,对吗?但这并不意味着您应该使用它。这是使演示变得简单并可以处理某些特定情况的功能之一。但一般来说,“发送到队列”是一种反模式。
[当您是消息产生者时,您只关心使用正确的路由密钥将消息发送到正确的交换机。当您是消息使用者时,您会关心消息目的地-您预订的队列。每天可以使用同一路由密钥将消息发送到同一交换机,每天每天数千次。但是,这并不意味着它将每次都到达相同的队列。
随着消息使用者上线和下线,他们可以创建新的队列和绑定并删除旧的队列和绑定。消息生产者和消费者的这种观点告诉了队列的性质:可以在需要时改变的邮政信箱。
我也建议不要直接使用amqplib。这是一个很棒的库,但是缺乏很多可用性。而是在amqplib顶部寻找一个好的库。
我更喜欢wascally, by LeanKit。它是基于amqplib的抽象要容易得多,并且提供了许多出色的功能。
最后,如果您在启动RMQ并与Node.js一起运行,设计与之配合使用的应用等方面苦于其他细节,请查看我的RabbitMQ For Devs课程-它从零到英雄,快速。 :)
这可能会对其他人有所帮助,但是用于内容类型的键名称在JavaScript代码中为contentType。使用Rabbit MQ的Web Gui,他们使用content_type作为键名。不同的键名来声明选项,因此请确保在正确的上下文中使用正确的键名。