我在我的Node代码中使用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) => {...});
答案 0 :(得分:2)
不知何故,我似乎无法让你的例子发布工作......虽然我没有看到任何特别错误。我不确定为什么我无法让你的示例代码正常工作。
但是我能够修改我自己的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”vhost中看到消息显示在“test.q”队列中(假设您已创建该队列)。
以下是来自RMQ管理插件的结果消息的屏幕截图:
旁注:
我建议不要使用sendToQueue
。正如我在RabbitMQ Patterns email course / ebook中所说的那样:
我花了一段时间才意识到这一点,但我现在看到RabbitMQ的“发送到队列”功能是一种反模式。
当然,它内置于库和协议中。它很方便,对吗?但这并不意味着你应该使用它。这是使演示简单并处理某些特定场景所存在的功能之一。但一般来说,“发送到队列”是一种反模式。
当您是消息生产者时,您只关心使用正确的路由密钥将消息发送到正确的交换机。当您是消息使用者时,您关心消息目标 - 您订阅的队列。可以每天使用相同的路由密钥将消息发送到同一交换机,每天数千次。但是,这并不意味着它每次都会到达同一个队列。
当消息使用者联机并脱机时,他们可以创建新的队列和绑定并删除旧的队列和绑定。消息生产者和消费者的这种观点表明了队列的性质:邮箱可以在需要时改变。
我还建议不要直接使用amqplib。这是一个很棒的图书馆,但它缺乏很多可用性。相反,在amqplib上寻找一个好的库。
我更喜欢wascally, by LeanKit。它在amqplib之上更容易抽象,并提供了许多强大的功能和特性。
最后,如果您在使用Node.js获取RMQ并运行其他细节,设计应用程序以使用它等等,请查看我的RabbitMQ For Devs课程 - 它从零到英雄,快。 :)
答案 1 :(得分:0)
这可能会对其他人有所帮助,但是用于内容类型的键名称在JavaScript代码中为 contentType 。通过使用Rabbit Gui的Web Gui,他们使用 content_type 作为键名。不同的键名称来声明选项,因此请确保在正确的上下文中使用正确的键。