2015-08-14 75 views
0

我使用ampq.node來爲我的節點代碼中的RabbitMQ訪問。我試圖使用publishsendToQueue方法,使用options參數將我的發佈消息(即時間戳和內容類型)包含在一些元數據中。無法使用RabbitMQ消息發佈選項?

但無論我傳遞給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,你必須提供回調函數的最後一個參數,否則,選項對象被忽略。所以一旦我改變了代碼以下,我開始看到正確的選項:

​​

回答

2

不知怎的,我似乎無法得到你的例子發佈工作...雖然我看不到任何東西特別是它錯了。我不知道爲什麼我無法讓您的示例代碼工作。

但是我能夠修改我自己的amqplib介紹代碼的一個版本,並讓它與您的選項一起工作就好了。

這裏是我的例子的完整代碼:

// test.js file 

var amqplib = require("amqplib"); 

var server = "amqp://test:[email protected]/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.q」隊列中出現(假設你已經創建了這個隊列)在你的「test-app」虛擬主機中。

下面是從RMQ管理插件所產生的消息的屏幕截圖:

message from rmq server


旁註:

我建議不要使用sendToQueue。正如我在我的RabbitMQ Patterns email course/ebook所說:

我花了一段時間才意識到這一點,但現在我看到RabbitMQ的「發送隊列」功能作爲反模式。

當然,它是建立在圖書館和協議。這很方便,對吧?但這並不意味着你應該使用它。這是使演示變得簡單並處理一些特定場景的功能之一。但一般來說,「發送隊列」是一種反模式。

當你是一個消息製作者時,你只關心使用正確的路由鍵將消息發送到正確的交換。當你是消息使用者時,你關心的是消息目標 - 你訂閱的隊列。一條消息可能會每天發送到同一個交換機,每天有數千次相同的路由密鑰。但是,這並不意味着它每次都會進入同一隊列。

隨着消息使用者聯機並脫機,他們可以創建新的隊列和綁定並刪除舊的隊列和綁定。消息製作者和消費者的這種觀點通知了隊列的性質:可以在需要時改變的郵箱。

我也建議不要直接使用amqplib。這是一個很棒的圖書館,但它缺乏很多可用性。相反,在amqplib之上尋找一個好的庫。我想要wascally, by LeanKit。在amqplib上這是一個非常容易的抽象,並提供了很多強大的功能。

最後,如果您在使用Node.js啓動並運行RMQ,設計應用程序以使用它等等方面遇到其他細節,請查看我的RabbitMQ For Devs課程 - 它從零到英雄,快速。 :)

+0

感謝您的詳細回覆Derick。我使用確認頻道的事實是否會成爲問題? (是的,我從我的示例中刪除了回調代碼 - 認爲它會使它看起來更乾淨)。 –

+0

老實說,從來沒有使用ConfirmChannel插件,所以我不知道這是否會導致這樣的事情。我不這麼認爲......但我不知道。 –