web-dev-qa-db-fra.com

RabbitMQ: Comment envoyer Python dictionnaire entre Python producteur et consommateur?)

J'essaie d'envoyer un dictionnaire python d'un producteur python) à un consommateur python utilisant RabbitMQ. Le producteur d'abord établit la connexion au serveur RabbitMQ local. Ensuite, il crée une file d'attente à laquelle le message sera remis, puis envoie le message. Le consommateur se connecte d'abord au serveur RabbitMQ, puis s'assure que la file d'attente existe en créant la même file d'attente. Il reçoit ensuite le message du producteur dans la fonction de rappel, et imprime la valeur 'id' (1). Voici les scripts pour le producteur et le consommateur:

script producteur.py:

import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(Host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)

message = {'id': 1, 'name': 'name1'}
channel.basic_publish(exchange='',
                      routing_key='task_queue',
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # make message persistent
                      ))
print(" [x] Sent %r" % message)
connection.close()

script consumer.py:

import pika
import time

connection = pika.BlockingConnection(pika.ConnectionParameters(Host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='task_queue', durable=True)
print(' [*] Waiting for messages. To exit press CTRL+C')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    print(body['id'])
    print(" [x] Done")
    ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_qos(prefetch_count=1)
channel.basic_consume(callback,
                      queue='task_queue')

channel.start_consuming()

Mais, lorsque je lance le producteur.py, j'obtiens cette erreur:

line 18, in <module>
    delivery_mode = 2, # make message persistent
  File "/Library/Python/2.7/site-packages/pika/adapters/blocking_connection.py", line 1978, in basic_publish
    mandatory, immediate)
  File "/Library/Python/2.7/site-packages/pika/adapters/blocking_connection.py", line 2064, in publish
    immediate=immediate)
  File "/Library/Python/2.7/site-packages/pika/channel.py", line 338, in basic_publish
    (properties, body))
  File "/Library/Python/2.7/site-packages/pika/channel.py", line 1150, in _send_method
    self.connection._send_method(self.channel_number, method_frame, content)
  File "/Library/Python/2.7/site-packages/pika/connection.py", line 1571, in _send_method
    self._send_message(channel_number, method_frame, content)
  File "/Library/Python/2.7/site-packages/pika/connection.py", line 1596, in _send_message
    content[1][s:e]).marshal())
TypeError: unhashable type

Quelqu'un pourrait-il m'aider? Merci!

24
Malgi

Vous ne pouvez pas envoyer de types natifs Python comme charge utile, vous devez d'abord les sérialiser. Je recommande d'utiliser JSON:

import json
channel.basic_publish(exchange='',
                  routing_key='task_queue',
                  body=json.dumps(message),
                  properties=pika.BasicProperties(
                     delivery_mode = 2, # make message persistent
                  ))

et

def callback(ch, method, properties, body):
print(" [x] Received %r" % json.loads(body))
35
Turn