2016-06-27 5 views
0

Ich möchte eine Nachricht (direkt) von einem Skript senden und dann verarbeiten, und senden Sie die Ergebnisse zurück. So ist es wie ein Doppel-Publish-Subscribe.Empfangen Sie eine Nachricht mit RabbitMQ dann verarbeiten Sie es und senden Sie dann die Ergebnisse zurück

Ich habe 2 Skripte:

  • Processer
  • Kunde

Der Kunde sendet eine Nachricht direkt (einfache Zeichenfolge) an die Processer, und als die Processer Skript zählt die Zeichen in der string und sendet die Ergebnisse an den Client zurück.

Dies ist, wie ich versucht zu tun: für eine Nachricht

Die Processer wartet, berechnet etwas und als Antworten zurück an den ursprünglichen Absender.

#Processer.py: 
import pika 
import sys 

#Sends back the score 
#addr: Connection address 
#exchName: Exchange name (where to send) 
#rKey: Name of the queue for direct messages 
#score: The detected score 
def SendActualScore(addr, exchName, rKey, score): 
    #Send the image thru the created channel with the given routing key (queue name) 
    channel.basic_publish(exchange=exchName, routing_key=rKey, body=score) 
    print "(*) Sent: " + score 

#When we receive something this is called 
def CallbackImg(ch, method, properties, body): 
    print "(*) Received: " + str(body) 
    score = str(len(body)) 
    #Send back the score 
    SendActualScore('localhost', 'valami', rKey, score) 


#Subscribe connection 
#Receive messages thru this 
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) 
channel = connection.channel() 
#RECEIVE MESSAGES - Subscribe 
channel.exchange_declare(exchange='valami', type='direct') 
#Define a queue, where we don't need the name 
#After we disconnected delete the queue (exclusive flag) 
result = channel.queue_declare(exclusive=True) 
#We need the name of our temporary queue 
queue_name = result.method.queue 

rKeys = sys.argv[1:] 
for rKey in rKeys: 
    channel.queue_bind(exchange='valami', queue=queue_name, routing_key = rKey) 

channel.basic_consume(CallbackImg, queue=queue_name, no_ack=True) 
print(' [*] Waiting for messages. To exit press CTRL+C') 
channel.start_consuming() 

Der Client sendet nur die Nachricht und wartet dann auf die Antwort.

#Client.py: 
import pika 
import sys 

connAddr = 'localhost' 

#Establish connection 
connection = pika.BlockingConnection(pika.ConnectionParameters(connAddr)) 
channel = connection.channel() 

#Define an exchange channel, we don't need a queue 
channel.exchange_declare(exchange='valami', type='direct') 

#Send the image thru the created channel 
channel.basic_publish(exchange='valami', routing_key='msg', body='Message in the body') 

print "[*] Sent" 

def Callback(ch, method, properties, body): 
    print "(*) Received: " + str(body) 

result = channel.queue_declare(exclusive=True) 
#We need the name of our temporary queue 
queue_name = result.method.queue 

channel.queue_bind(exchange='valami', queue=queue_name) 

channel.basic_consume(Callback, queue=queue_name, no_ack=True) 
print(' [*] Waiting for messages. To exit press CTRL+C') 
channel.start_consuming() 

Es könnte mehrere Clients sein, und ich weiß nicht, wie direkt die Nachrichten senden zu ihnen zurück.

Antwort

0

Haben Sie die Tutorials für RPC in RabbitMQ mit Python und Pika überprüft? http://www.rabbitmq.com/tutorials/tutorial-six-python.html


Der Kern dessen, was Sie in Ihrem Client tun müssen, ist in der RPC-Tutorial, aber mit ein paar Modifikationen gefunden.

In Ihrem Client müssen Sie eine exklusive Warteschlange erstellen - genau wie auf Ihrem Server.

Wenn Sie Ihre Nachricht vom Client senden, müssen Sie die reply_to auf den Namen des Kunden exklusiver Warteschlange setzen

aus dem Tutorial:

channel.basic_publish(exchange='', 
         routing_key='rpc_queue', 
         properties=pika.BasicProperties(
          reply_to = callback_queue, 
          ), 
         body=request) 

auf dem Server, wenn Sie einen Empfang Nachricht, müssen Sie die reply_to Header aus der Nachricht und dann basic_publish die Antwort auf diese Warteschlange lesen.


Anstatt darüber nachzudenken, „Client“ und „Server“ kann es hilfreich sein, diese von „-Meldung Produzenten“ und „Nachrichtenkonsumenten“ in Bezug zu gestalten.

In Ihrem Szenario benötigen Sie beide Prozesse als Publisher und als Konsument. Der "Client" wird die ursprüngliche Nachricht veröffentlichen und die Antwort konsumieren. Der "Server" wird die ursprüngliche Nachricht konsumieren und eine Antwort veröffentlichen.

Der einzige wirkliche Unterschied in Ihrem Code wird die Verwendung der reply_to Header auf der ursprünglichen Nachricht sein. Dies ist der Name der Warteschlange, in der Sie die Antwort veröffentlichen sollten.

Hoffe, dass hilft!


P.S. Ich umreiße den Kern dieser in meinem RabbitMQ Patterns eBook - sowohl RPC und Anfrage/Antwort wie Sie benötigen. Das Buch spricht in Prinzipien und Mustern, nicht in einer bestimmten Programmiersprache (obwohl ich hauptsächlich node.js schreibe und Python nicht wirklich kenne).

+0

Ja, ich tat, aber ich muss das mit Pub-Sub arbeiten. – Gabe

Verwandte Themen