簡體   English   中英

Python Pika - 消費者進入線程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM