When sending a message via Rabbit MQ, a sender can chose to identify itself, or hid its identity, but it cannot lie.
I modified the Pika examples to work with hard coded user-id and password. Specifically, I added:
properties = pika.BasicProperties(user_id=rabbit_userid);
And used that as a parameter in:
channel.basic_publish(exchange='', properties=properties, routing_key='hello', body='Hello World!')
On the receiving side, in the callback, make use of the properties:
def callback(ch, method, properties, body): print(" [x] Received %r" % body) print("Message user_id is %s " % properties.user_id)
And the output looks like this:
$ python recv.py & [1] 5062 $ [*] Waiting for messages. To exit press CTRL+C $ python sender.py [x] Sent 'Hello World!' [x] Received 'Hello World!' Message user_id is a5f56bdb395f53864a80b95f45dc395e94c546c7
Modify the sender so the ids don’t match and:
raise exceptions.ChannelClosed(method.reply_code, method.reply_text) pika.exceptions.ChannelClosed: (406, "PRECONDITION_FAILED - user_id property set to 'rabbit_userid' but authenticated user was 'a5f56bdb395f53864a80b95f45dc395e94c546c7'")
Here is the complete code.
sender.py
#!/usr/bin/env python import pika rabbit_host = '10.149.2.1' rabbit_userid = 'a5f56bdb395f53864a80b95f45dc395e94c546c7' rabbit_password = '06814091f31ad50b55a3509e9e3916082cce556d' credentials = pika.PlainCredentials(rabbit_userid, rabbit_password) connection = pika.BlockingConnection(pika.ConnectionParameters( host=rabbit_host, credentials=credentials)) channel = connection.channel() channel.queue_declare(queue='hello') properties = pika.BasicProperties(user_id=rabbit_userid); channel.basic_publish(exchange='', properties=properties, routing_key='hello', body='Hello World!') print(" [x] Sent 'Hello World!'") connection.close()
recv.py
#!/usr/bin/env python import pika rabbit_host = '10.149.2.1' rabbit_userid = 'a5f56bdb395f53864a80b95f45dc395e94c546c7' rabbit_password = '06814091f31ad50b55a3509e9e3916082cce556d' credentials = pika.PlainCredentials(rabbit_userid, rabbit_password) connection = pika.BlockingConnection(pika.ConnectionParameters( host=rabbit_host, credentials=credentials)) channel = connection.channel() channel.queue_declare(queue='hello') def callback(ch, method, properties, body): print(" [x] Received %r" % body) print("Message user_id is %s " % properties.user_id) channel.basic_consume(callback, queue='hello', no_ack=True) print(' [*] Waiting for messages. To exit press CTRL+C') channel.start_consuming()
Hi , how do I know if the message is queued after line 14 in sender.py?
It really depends on the context: in a test environemnet, pull it out on the other end. In a production environment, without additional code, you don’t. You can register a callback to check the response code via add_on_return_callback(callback) but that only gets called on failure. If you use a basic_ack, you get a positive callback. Between those two callbacks, you should get what you need.