[英]Python Pika - Consumer into Thread
我正在開發一個帶有后台線程的 Python 應用程序,用於從 RabbitMQ 隊列(主題場景)中消費消息。
我在按鈕的 on_click 事件上啟動線程。 這是我的代碼,請注意“#self.receive_command()”。
def on_click_start_call(self,widget):
t_msg = threading.Thread(target=self.receive_command)
t_msg.start()
t_msg.join(0)
#self.receive_command()
def receive_command(self):
syslog.syslog("ENTERED")
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
syslog.syslog("1")
channel = connection.channel()
syslog.syslog("2")
channel.exchange_declare(exchange='STORE_CMD', type='topic')
syslog.syslog("3")
result = channel.queue_declare(exclusive=True)
syslog.syslog("4")
queue_name = result.method.queue
syslog.syslog("5")
def callback_rabbit(ch,method,properties,body):
syslog.syslog("RICEVUTO MSG: RKEY:"+method.routing_key+" MSG: "+body+"\n")
syslog.syslog("6")
channel.queue_bind(exchange='STORE_CMD', queue=queue_name , routing_key='test.routing.key')
syslog.syslog("7")
channel.basic_consume(callback_rabbit,queue=queue_name,no_ack=True)
syslog.syslog("8")
channel.start_consuming()
如果我運行此代碼,我在 syslog 上看不到消息 1、2、3、5、6、7、8 但我只能看到“ENTERED”。 因此,代碼被鎖定在 pika.BlokingConnection 上。
如果我運行相同的代碼(注釋線程指令並取消對函數的直接調用),所有工作都按預期工作並且消息被正確接收。
有什么解決方案可以讓消費者進入線程?
提前致謝
戴維德
我已經在我的機器上測試了代碼,並使用了最新版本的Pika。 它工作正常。 Pika存在線程問題,但只要您為每個線程創建一個連接,它就不應該成為問題。
如果您遇到問題,很可能是因為舊版Pika中的錯誤,或導致問題的線程無關的問題。
我建議您避免使用0.9.13,因為存在多個錯誤,但很快就會發布
0.9.14
0.10.0。
[編輯] Pika 0.9.14已經發布。
這是我使用的代碼。
def receive_command():
print("ENTERED")
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
print("1")
channel = connection.channel()
print("2")
channel.exchange_declare(exchange='STORE_CMD', type='topic')
print("3")
result = channel.queue_declare(exclusive=True)
print("4")
queue_name = result.method.queue
print("5")
def callback_rabbit(ch,method,properties,body):
print("RICEVUTO MSG: RKEY:"+method.routing_key+" MSG: "+body+"\n")
print("6")
channel.queue_bind(exchange='STORE_CMD', queue=queue_name , routing_key='test.routing.key')
print("7")
channel.basic_consume(callback_rabbit,queue=queue_name,no_ack=True)
print("8")
channel.start_consuming()
def start():
t_msg = threading.Thread(target=receive_command)
t_msg.start()
t_msg.join(0)
#self.receive_command()
start()
另一種方法是傳遞給線程方法channel.start_consuming
作為目標,然后將你的回調傳遞給consume
方法。 用法: consume(callback=your_method, queue=your_queue)
import threading
def consume(self, *args, **kwargs):
if "channel" not in kwargs \
or "callback" not in kwargs \
or "queue" not in kwargs \
or not callable(kwargs["callback"]):
return None
channel = kwargs["channel"]
callback = kwargs["callback"]
queue = kwargs["queue"]
channel.basic_consume(callback, queue=queue, no_ack=True)
t1 = threading.Thread(target=channel.start_consuming)
t1.start()
t1.join(0)
dorintufar建議的方法對我很有用,但由於我的 pika 包裝器版本,我遇到了 TypeError。 如果您收到此類錯誤,建議您將 channel.basic_consume 中的參數順序從:
channel.basic_consume(callback, queue=queue, no_ack=True)
至:
channel.basic_consume(queue, callback, no_ack=True)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.