0

Python、rabbitmq、pika、rabbit.js、node.js を使用しています。

アイデアは、クライアントにメッセージを送信し、それに応じて行動することです。送信されるメッセージには複数の種類があります。

したがって、サーバー側には、メッセージを受信するメソッドと、メッセージを送信する交換があります。

import pika
def send(exchange, message):
    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
    channel = connection.channel()
    channel.exchange_declare(exchange=exchange, type='fanout',)
    channel.basic_publish(exchange=exchange,
                          routing_key='',
                          body=message)

まだサーバー側では、node.js を使用して、複数のコンテキストがあり、交換は名前に従って呼び出すと思います (注:「クライアント」は、サーバーに接続されているクライアントのリストを指します)。

var context = require('rabbit.js').createContext();

context.on('ready', function() {

    var consumer_1 = context.socket('SUB');
    var consumer_2 = context.socket('SUB');

    consumer_1.setEncoding('utf8');
    consumer_1.connect('consumer_1', function (){
    consumer_1.on('data', function(data){
        try {
            io.sockets.emit("client_method_1", data);
        }catch(err){
            console.log("[CONSUMER 1 ERROR] " + err);
        }

    });

    consumer_2.setEncoding('utf8');
    consumer_2.connect('client_method_2', function (){
    consumer_2.on('data', function(data){
        try {
            clients[data.client].emit('client_method_2', data.action );
        }
        catch(err) {
            console.log("[CONSUMER 2 ERROR]: " + err);
        }
    });

});

ここで起こっていることは、consumer_1 がすべてのクライアントにメッセージを送信し、consumer_2 が特定のクライアントに送信し、その部分がうまく機能していることです。

問題は、すべての消費者がすべての取引所からメッセージを受信して​​いることです。consumer_1 にメッセージを送信しようとすると、consumer_2 もメッセージを受信します。

実用的な面では、私が呼び出すと:

send('consumer_1', data)

結果は次のようになります。

  • ノードは「client_method_1」に出力します。
  • また、「client_method_2」に発行しようとします。

他のコンシューマーを呼び出さずに特定のコンシューマーを呼び出すにはどうすればよいですか?

または、コンシューマを 1 つだけ宣言し、データをフィルタリングして別のメソッドを呼び出す必要がありますか?

編集:

TokenMacGuy のアドバイスに従って、交換タイプを「トピック」または「直接」に変更しようとしました。それはまさに私が望むことをするはずです。

しかし、常にありますが、どういうわけか交換を再宣言できません。ノードを再起動すると、次のエラーが発生し続けます。

[(406, "PRECONDITION_FAILED - cannot redeclare exchange 'consumer_1' in vhost '/' with different type, durable, internal or autodelete value")]

わかりましたので、rabbitmq で list_exchanged を確認しましたが、コンシューマーはまだ「ファンアウト」のままです。

    direct
amq.direct  direct
amq.fanout  fanout
amq.headers headers
amq.match   headers
amq.rabbitmq.log    topic
amq.rabbitmq.trace  topic
amq.topic   topic
celery  direct
celery.pidbox   fanout
consumer_1    fanout
consumer_2    fanout
consumer_3    fanout

次の動きは、rabbitmq を停止、リセット (および後で強制リセット)、および開始することによってリセットすることでした。

consumer_1 にメッセージを送信しました

これで、consumer_1 は「direct」としてリストされます。

    direct
amq.direct  direct
amq.fanout  fanout
amq.headers headers
amq.match   headers
amq.rabbitmq.log    topic
amq.rabbitmq.trace  topic
amq.topic   topic
celery  direct
celery.pidbox   fanout
consumer_1    direct
consumer_2    fanout
consumer_3    fanout

わかりました、consumer_1 だけを呼び出し、他のすべてがリストに表示されるので、その情報を含むファイルが必要です。どこ?何も思いつきません!!

とにかく、consumer_1 で同じ PRECONDITION_FAILED エラーが発生します。

何か案は?

4

1 に答える 1