尽管显然不要在多个线程之间使用单个PIKA连接,但是我们可以使用在多个线程之间获得连接的通道吗?我这样做时遇到此错误,答案似乎是否定的。只是发布以供参考
INFO 2019-02-07 13:14:12,927 pika.connection _on_terminate 2095: Disconnected from RabbitMQ at 127.0.0.1:5672 (505): UNEXPECTED_FRAME - expected content header for class 60, got non content header frame instead
答案 0 :(得分:0)
尽管显然不要在多个线程中使用单个PIKA连接,但是我们可以使用在多个线程中获得连接的通道吗。
我是Pika的维护者之一,不,您不能跨线程使用连接或通道。已记录。
注意: RabbitMQ团队监视rabbitmq-users
mailing list,并且有时仅在StackOverflow上回答问题。
答案 1 :(得分:0)
我这样做如下
Example using PIKA consumer without blocking thread - PIKA and GRPC Streaming
###########
def grpc_test(self, request, context):
# A response streaming GRPC implementation - Client gets stream of messages
message_queue = Queue.Queue()
app = request
def rmq_callback(data):
print("Got a call back from RMQ Client")
message_queue.put(data)
# Register with RabbitMQ for Data
# thread safe - create a connection here and a channel
pikaconsumer = TestConsumer()
# Client want to listen on this queue
pikaconsumer.listen_on_queue("xxxx", rmq_callback)
# use the connection and channel in a new thread (and no other thread)
t= threading.Thread(target=pikaconsumer.start_consuming)
t.start()
while True:
date = message_queue.get(True)
protobuf_obj = proto.Data()
message.ParseFromString(obj)
yield message
###########
class TestConsumer(object):
def __init__(self):
amqp_url ='amqp://guest:guest@127.0.0.1:5672/'
parameters = pika.URLParameters(amqp_url)
connection = pika.BlockingConnection(parameters)
self._channel = connection.channel()
def listen_on_queue(self,queue_name,exchange,routing_keys,_callback):
# In case queue is not there - create a queue
self._channel.queue_declare(queue=queue_name,auto_delete=True,)
for routing_key in routing_keys:
self._channel.queue_bind(queue_name,
exchange, str(routing_key))
LOGGER.info('Binding Exchange[%s] to Queue[%s] with RoutingKey[%s]',
exchange, queue_name, str(routing_key))
def __on_message(channel, method_frame, header_frame, body, callback=()):
print(method_frame.delivery_tag)
callback(body)
channel.basic_ack(delivery_tag=method_frame.delivery_tag)
self._consumer_tag = self._channel.basic_consume(partial(__on_message,
callback=_callback), queue_name)
def start_consuming(self):
self._channel.start_consuming()