RPC:Client向Server发送消息,Server收到后回复确认报文。即两边都同时是生产者和消费者。
代码饭粒:client发送请求第?个斐波那契数,server接到请求后返回相应的斐波那契数
# Client
import pika import uuid import time class FibonacciRpcClient(object): def __init__(self): self.connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) self.channel = self.connection.channel() result = self.channel.queue_declare(exclusive=True) # 自动创建queue self.callback_queue = result.method.queue self.channel.basic_consume( # 接收消息 self.on_response, # 只要一收到消息就调用on_response no_ack=True, queue=self.callback_queue ) def on_response(self, ch, method, props, body): if self.corr_id == props.correlation_id: # 判断server返回的correlation_id与刚刚发送过去的corr_id是否相等,若相等则为刚刚发送消息的ACK self.response = body def call(self, n): self.response = None self.corr_id = str(uuid.uuid1()) # uuid.uuid1():基于时间戳生成唯一ID self.channel.basic_publish(exchange='', # 发送消息 routing_key='rpc_queue', properties=pika.BasicProperties( reply_to=self.callback_queue, correlation_id=self.corr_id, ), body=str(n)) # 不能发送数字,所以要转成str while self.response is None: self.connection.process_data_events() # 相当于非阻塞版的start_consuming() print("no message...") time.sleep(0.5) return int(self.response) fibonacci_rpc = FibonacciRpcClient() print(" [x] Requesting fib(10)") response = fibonacci_rpc.call(10) print(" [.] Got %r" % response)
# Server
import pika import time connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) channel = connection.channel() channel.queue_declare(queue='rpc_queue') def fib(n): # 生成斐波那契数 if n == 0: return 0 elif n == 1: return 1 else: return fib(n - 1) + fib(n - 2) def on_request(ch, method, props, body): n = int(body) print(" [.] fib(%s)" % n) response = fib(n) ch.basic_publish(exchange='', # 发送消息 routing_key=props.reply_to, # 发送到client发过来的reply队列 properties=pika.BasicProperties(correlation_id= \ props.correlation_id), # 将client发送过来的corr_id发回去,用于client验证消息对应的ACK body=str(response)) ch.basic_ack(delivery_tag=method.delivery_tag) channel.basic_consume(on_request, # 只要一收到消息就调用on_request queue='rpc_queue') print(" [x] Awaiting RPC requests") channel.start_consuming()