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.