- RPC, synchronous message
In fact, the server and the client each define a message queue and send messages to each other. , the client synchronously waits for the result to return after sending the message
- Points to Note
Specify the reply queue, corrId when sending a message :
//Send a message, specifying the queue where the reply message is located BasicProperties props=new BasicProperties.Builder().correlationId(corrId).replyTo(queueName).build(); channel.basicPublish("", "rpc_queue", props, SerializationUtils.serialize(mes));
Listen to the queue and wait for server feedback (blocking) :
//Listen to the queue and receive the server reply message while(true){ QueueingConsumer.Delivery delivery=consumer.nextDelivery();//堵塞 //do something break; }
After receiving the message, the server writes back the processing result :
channel.basicPublish("", properties.getReplyTo() ,new BasicProperties.Builder().correlationId(properties.getCorrelationId()).build(), SerializationUtils.serialize("response:"+mes));
The server enables manual answering :
//Turn off the automatic response mechanism, which is enabled by default; at this time, you need to manually perform the response channel.basicConsume("rpc_queue", false, consumer); channel.basicAck(envelope.getDeliveryTag(), false);
Limit the maximum processing capacity of the server :
channel.basicQos(1);
- RPC server
package com.demo.mq.rabbitmq.example06; import java.io.IOException; import java.io.Serializable; import org.apache.commons.lang3.SerializationUtils; import com.demo.mq.rabbitmq.MqManager; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.AMQP.BasicProperties; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.Consumer; import com.rabbitmq.client.DefaultConsumer; import com.rabbitmq.client.Envelope; /** * RPC server * @author sheungxin * */ public class RPCServer{ /** * RPC server, declare a service processing queue, after receiving the message processing, write the result back to the client * The manual response mechanism needs to be turned on to ensure that the service execution is completed * @param object message body * @throws IOException */ public static void sendAToB(Serializable object) throws Exception{ Connection conn=MqManager.newConnection(); Channel channel=conn.createChannel(); channel.queueDeclare("rpc_queue", false, false, false, null); channel.basicQos(1); Consumer consumer=new DefaultConsumer(channel){ @Override public void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) throws IOException{ String mes=SerializationUtils.deserialize(body); System.out.println(envelope.getRoutingKey()+":Received :'"+mes+"' done"); //After receiving the message, write back the message to the sender: specify the queue where the sender is located (properties.getReplyTo()), correlationId channel.basicPublish ("", properties.getReplyTo (), new BasicProperties.Builder().correlationId(properties.getCorrelationId()).build(), SerializationUtils.serialize("response:"+mes)); channel.basicAck(envelope.getDeliveryTag(), false); } }; //Turn off the automatic response mechanism, which is enabled by default; at this time, you need to manually perform the response channel.basicConsume("rpc_queue", false, consumer); System.out.println("*********8"); } public static void main(String[] args) throws Exception { sendAToB("Hello World !"); } }
- RPC client
package com.demo.mq.rabbitmq.example06; import java.util.UUID; import org.apache.commons.lang3.SerializationUtils; import com.demo.mq.rabbitmq.MqManager; import com.rabbitmq.client.AMQP.BasicProperties; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.QueueingConsumer; /** * RPC client * @author sheungxin * */ @SuppressWarnings("deprecation") public class RPCClient { /** * RPC client: send a message to the server processing queue, specify correlationId and reply queue name when sending, and establish a consumer on the reply queue to monitor and receive reply messages * @param month * @throws Exception */ public static String call(String mes) throws Exception{ String response=null; Connection conn=MqManager.newConnection(); Channel channel=conn.createChannel(); //Create a temporary queue for receiving reply messages String queueName=channel.queueDeclare().getQueue(); QueueingConsumer consumer=new QueueingConsumer(channel); channel.basicConsume(queueName, true, consumer); String corrId=UUID.randomUUID().toString(); //Send a message, specifying the queue where the reply message is located BasicProperties props=new BasicProperties.Builder().correlationId(corrId).replyTo(queueName).build(); channel.basicPublish("", "rpc_queue", props, SerializationUtils.serialize(mes)); //Listen to the queue and receive the server reply message while(true){ QueueingConsumer.Delivery delivery=consumer.nextDelivery(); if(delivery.getProperties().getCorrelationId().equals(corrId)){ response=SerializationUtils.deserialize(delivery.getBody()); break; } } return response; } public static void main(String[] args) throws Exception { System.out.println(call("hello world")); System.out.println("waiting for rpc is over"); } }