2016-09-01 2 views
1

Ich habe eine Funktion für eine Nachricht an RabbitMQ Warteschlangen wie folgt:node.js imqplib sendToQueue zu RabbitMQ hängt

var amqp = require('amqplib/callback_api'); 

var _queueURL = 'amqp://127.0.0.1'; 
var _toBlahBlahQueueName = 'blahblah'; 

var self = module.exports = { 
    queueMessage: function (msgObj, callback) { 
    try { 
     amqp.connect(_queueURL, function (err, connection) { 
     if (err) { 
      callback(err); 
     } 

     connection.createChannel(function (err, channel) { 
      if (err) { 
      callback(err); 
      } 

      channel.assertQueue(_toBlahBlahQueueName, { durable: true }, function (err, _ok) { 
      if (err) { 
       callback(err); 
      } 

      var msg = new Buffer(JSON.stringify(msgObj)); 

      channel.sendToQueue(_toBlahBlahQueueName, msg, { persistent: true }, function (err, ok) { 
       if (err) { 
       console.log(err); 
       callback(err); 
       } 

       console.log('published', ok); 

       channel.connection.close(); 
       callback(null, { message: 'queued' }); 
      }); 
      }); 
     }); 
     }); 
    } 
    catch (e) { 
     console.log(e.stack); 
     callback(e); 
    } 
    } 
}; 

Ich bin die Funktion queueMessage mit Nachrichten aufrufen, die über 250K lang sind.

Der sendToQueue-Aufruf hängt jedes Mal. Es sitzt nur da, ohne einen Fehler zu melden. Die Nachricht scheint jedoch in die Warteschlange eingereiht zu werden!

Das Serverprotokoll hat die Fehlermeldung: Client unerwartet geschlossen TCP-Verbindung

Vielen Dank für jede Hilfe!

Antwort

2

amqplib unterstützt keinen Rückruf für sendToQueue oder publish.

the documentation zeigt dies keine Option ist:

Kanal # sendToQueue Versprechen und Rückrufe

sendToQueue (Queue, Inhalt, [Optionen])

eine einzelne Nachricht mit dem Inhalt senden als Puffer für die spezifische Queue namens Bypass-Routing gegeben. Die Optionen und der Rückgabewert sind exakt die gleichen wie für publish.

Um dies zu umgehen, müssen Sie sendToQueue aufrufen, als wäre es eine synchrone Nachricht.

Wenn Sie die App sofort beenden möchten, müssen Sie einige Millisekunden warten. Wenn Sie dies nicht tun, wird die Nachricht nicht gesendet. Hier

ist ein Beispiel, wie Sie Ihren Code ändern könnte auf diese Weise funktionieren:

channel.sendToQueue(_toBlahBlahQueueName, msg, { persistent: true }); 
setTimeout(function() { 
    channel.connection.close(); 
    callback(null, { message: 'queued' }); 
}, 500); 
+0

Das funktionierte. Vielen Dank! Gibt es eine Bibliothek, die das besser macht? Scheint ineffizient. Eine letzte Frage, wenn ich kann ... Was ist der beste Weg, mehrere Nachrichten in Serie zu senden? Muss ich für jede Nachricht die Verbindung und die Channel- und Assert-Warteschlange öffnen? Oder kann ich, sagen wir, die Warteschlange quittieren und dann einen Stapel Nachrichten senden? Vielen Dank!! –

+0

leider, nein, gibt es nicht. amqplib ist die Standardbibliothek, die sogar das rabbitmq-Team für node.js empfiehlt. Es gibt andere Bibliotheken, die auf amqplib basieren, die einige Dinge einfacher machen ... aber keine von ihnen hat eine gute Lösung für dieses spezielle Szenario. –

Verwandte Themen