LavinMQ Direct Reply-to

Direct Reply-to

LavinMQ allows you to pass a response directly to the client, avoiding creating a response queue to wait on. To do so, set reply-to to amq.direct.reply-to. Send a message in no-ack mode. LavinMQ generates a special name that the target server sees as the routing key. The remote machine then publishes the result to the default exchange. No queue is created in the process. A direct reply allows you to avoid maintaining a long-lived queue. It also lets you avoid creating short-lived queues that utilize memory.

Using Direct Reply-to in LavinMQ

To use the direct reply feature, use the reply-to header with the amq.direct.reply-to queue. In this RPC example, we send a simple ping request to a remote machine.

Start by consuming from the amq.direct.reply-to queue on your client to avoid missing the response:

def client_consumer_callback(ch, method, properties, body):
msg = body.decode('utf-8')
if msg in "Hello from Consumer":
print("TARGET MACHINE IS ACTIVE")
global RECEIVED_HELLO
RECEIVED_HELLO = True
else:
print("RECEIVED UNEXPECTED MESSAGE")
ch.close()
channel.consume("amq.direct.reply-to", on_message_callback=client_consumer_callback)

The consumer checks that the response message contains a greeting from the server.

Next, create another consumer to mimic a remote computer:

def consumer_callback(ch, method, properties, body):
msg = body.decode('utf-8')
if msg in "Hello World":
basic_props = BasicProperties()
ch.basic_publish(exchange='', routing_key=properties.reply_to, properties=basic_props, body="Hello from Consumer")
ch.basic_ack(delivery_tag=method.delivery_tag)
else:
print("RECEIVED UNEXPECTED MESSAGE")
channel.consume("amq.direct.reply-to", on_message_callback=consumer_callback)

This consumer receives the request, checks that the message contains Hello World, and sends back the greeting. Notice that both consumers subscribe to amq.direct.reply-to.

Finally, send a message to the queue using the reply-to header:

basic_props = BasicProperties(
reply_to="amq.direct.reply-to"
)

channel.basic_publish('', routing_key="", properties=basic_props, body="Hello World")

You can use this method to fetch data or perform tasks such as registering users on a mobile application. We created a simple health check.

RPC differs somewhat from the traditional publisher-subscriber model LavinMQ is known for. No queues are created and the process sends information directly to the client using a direct reply.

When using RPC this way:

  • Try to establish a connection to the client using the generated name on a disposal channel to see if the client still exists
  • Set the immediate flag to false when publishing
  • Start consuming from the amq.lavinmq.reply-to before publishing your message
  • Set the mandatory flag if using amq.lavinmq.reply-to to create error logs
  • Do not set the mandatory flag when using a direct-reply if using amq.lavinmq.reply-to.* as your queue

These tips allow you to know when something goes wrong. They also help you handle issues without losing messages.


NOTE: LavinMQ supports the use of amq.rabbitmq.reply-to to allow for compatibility with other brokers.