Topic exchange is powerful and can behave like other exchanges.

When a queue is bound with # (hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange.

When special characters * (star) and # (hash) aren't used in bindings, the topic exchange will behave just like a direct one.

Putting it all together

We're going to use a topic exchange in our logging system. We'll start off with a working assumption that the routing keys of logs will have two words: <facility>.<severity>.

The code is almost the same as in the previous tutorial.

emit_log_topic.py (source)

#!/usr/bin/env python
import pika
import sys

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

channel.exchange_declare(exchange='topic_logs', exchange_type='topic')

routing_key = sys.argv[1]iflen(sys.argv)>2else'anonymous.info'
message =' '.join(sys.argv[2:])or'Hello World!'
channel.basic_publish(
exchange='topic_logs', routing_key=routing_key, body=message)
print(f" [x] Sent {routing_key}:{message}")
connection.close()

receive_logs_topic.py (source)

#!/usr/bin/env python
import pika
import sys

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

channel.exchange_declare(exchange='topic_logs', exchange_type='topic')

result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queue

binding_keys = sys.argv[1:]
ifnot binding_keys:
sys.stderr.write("Usage: %s [binding_key]...\n"% sys.argv[0])
sys.exit(1)

for binding_key in binding_keys:
channel.queue_bind(
exchange='topic_logs', queue=queue_name, routing_key=binding_key)

print(' [*] Waiting for logs. To exit press CTRL+C')


defcallback(ch, method, properties, body):
print(f" [x] {method.routing_key}:{body}")


channel.basic_consume(
queue=queue_name, on_message_callback=callback, auto_ack=True)

channel.start_consuming()

To receive all the logs run:

python receive_logs_topic.py "#"

To receive all logs from the facility kern:

python receive_logs_topic.py "kern.*"

Or if you want to hear only about critical logs:

python receive_logs_topic.py "*.critical"

You can create multiple bindings:

python receive_logs_topic.py "kern.*""*.critical"

And to emit a log with a routing key kern.critical type:

python emit_log_topic.py "kern.critical""A critical kernel error"

Have fun playing with these programs. Note that the code doesn't make any assumption about the routing or binding keys, you may want to play with more than two routing key parameters.

Move on to tutorial 6 to learn about RPC.

AltStyle によって変換されたページ (->オリジナル) /