やったこと
RabbitMQに接続する
まずはRabbitMQに接続する。
チュートリアル上のコードは以下となっているが、RabbitMQにID/PASSWORDを設定している場合は、これだけだと認証エラーになってしまう。
import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() connection.close()
エラー
pika.exceptions.ProbableAuthenticationError: ConnectionClosedByBroker: (403) 'ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.'
以下のように認証情報を渡す必要がある。
import pika credentials = pika.PlainCredentials("admin", "password") connection = pika.BlockingConnection( pika.ConnectionParameters("localhost", 5672, "/", credentials) ) channel = connection.channel() connection.close()
※ 公式ドキュメントは以下
pika.readthedocs.io
キューを作成する
以下で「hello」という名前のキューを作成する。
※ 事前にRabbitMQにキューを作成しておく必要はない。
channel.queue_declare(queue="hello")
以下のように、管理画面上でキューが作成されていることを確認できる。
メッセージを送信する
以下で「Hello World!」というメッセージをキューに送信する。
channel.basic_publish(exchange="", routing_key="hello", body="Hello World!")
以下のように、管理画面上でメッセージを確認できる。
メッセージを受信する
次にメッセージを受信する側のコードを書く。
別のPythonファイルに以下を書いて実行すると、プロセスが実行中の状態になる。
import pika credentials = pika.PlainCredentials("admin", "password") connection = pika.BlockingConnection( pika.ConnectionParameters("localhost", 5672, "/", credentials) ) channel = connection.channel() channel.queue_declare(queue="hello") def callback(ch, method, properties, body): print(" [x] Received %r" % body) channel.basic_consume(queue="hello", on_message_callback=callback, auto_ack=True) channel.start_consuming()
この状態で、別のターミナルなどからメッセージを送信すると、メッセージがコンソール上に出力される。
$ python receive.py [x] Received b'Hello World!' [x] Received b'Hello World!' [x] Received b'Hello World!'
また、管理画面上でキュー上のメッセージは空になってることを確認できる。
その他に試してみたこと
チュートリアルにはないが以下を試してみた。
送信側のqueue_declare
のキュー名を変える。
送信側のqueue_declare
のキュー名を以下のように変えてみた。
channel.queue_declare(queue="hello2")
メッセージ送信先のキューと受信側が待ち受けているキューが違うので、受信側はメッセージを受信できなくのではないかと予想していたが、結果はメッセージを受信した。
ドキュメントをよく読むと、queue_declare
がやることは以下の2つとのことだった。
- キューが存在するかチェックする。
- キューが存在しなければ作成する。
Declare queue, create if needed. This method creates or checks a queue.
従って、「どのキューにメッセージを送信するか」を指定しているのはqueue_declare
ではなかった。
「どのキューにメッセージを送信するか」を指定しているのは、basic_publish
のrouting_key
の方だった。
The queue name needs to be specified in the routing_key parameter.
routing_key
のキュー名を変える。
上記を踏まえて、basic_publish
のrouting_key
のキュー名を以下のように変更してみた。
channel.basic_publish(exchange="", routing_key="hello2", body="Hello World!")
今度は予想通り、受信側はメッセージを受信できなかった。
尚、存在しないキュー名を指定しても特にエラーは発生しなかったが、これは「存在しないキューに送られたメッセージは捨てられる」というRabbitMQの仕様らしい。
If we send a message to non-existing location, RabbitMQ will just drop the message.
以上