本文已参与「新人创作礼」活动,一起开启掘金创作之路
1.创建生产者ReplyToProducer
package com.rabbit.fisher.setmsg;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeoutException;
/**
*消息的属性控制
*/
public class ReplyToProducer
{
public final static String EXCHANGE_NAME="replyto";
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//在信道中设置交换器(这里选择直接交换器direct)
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//响应QueueName,消费者将会把要返回的信息发送到该Queue
String responseQueue = channel.queueDeclare().getQueue();
//申明一个消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("Receive[" + envelope.getRoutingKey() + "]" + message);
}
};
//消费者应答队列上的消息
channel.basicConsume(responseQueue, true, consumer);
//消息的唯一ID
String msgId = UUID.randomUUID().toString();
//设置消息中的应答属性
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder().replyTo(responseQueue).messageId(msgId).build();
//申明路由键及消息体
String route ="error";
String msg = "Hello World";
//发布消息(设置交换器、路由键、参数、消息内容)
channel.basicPublish(EXCHANGE_NAME, route, properties, msg.getBytes());
System.out.println("Send:" + route + ";" + msg);
}
}
replyTo属性构建回复消息的私有响应队列,在生产者中,先申明一个队列responseQueue,用于消费者将返回的消息发送到这个队列中,再将这个队列名称添加到属性properties中,供消费者使用,最后在发送消息时,把属性properties作为入参传入。
在生产者中,申明一个消费者,用于完成第4步,获取应答消息,而且消费的是发送消息使用的同一个队列responseQueue
2.创建一个消费者ReplyToConsumer
package com.rabbit.fisher.setmsg;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*消息属性的控制
*/
public class ReplyToConsumer
{
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
final Channel channel = connection.createChannel();
//在信道中设置交换器
channel.exchangeDeclare(ReplyToProducer.EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
//申明队列
String queueName = channel.queueDeclare().getQueue();
//绑定:将队列与交换器通过路由键绑定
String routeKey = "error";
channel.queueBind(queueName, ReplyToProducer.EXCHANGE_NAME, routeKey);
System.out.println("waiting for message ......");
//申明一个消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("Receive[" + envelope.getRoutingKey() + "]" + message);
//从消息中拿到相关属性(确定要应答的消息ID)
AMQP.BasicProperties responseProperties = new AMQP.BasicProperties.Builder().replyTo(properties.getReplyTo())
.correlationId(properties.getMessageId()).build();
//消费者要消费时,同时需要作为生产者生产消息
channel.basicPublish("", responseProperties.getReplyTo(), responseProperties, ("Feedback," + message).getBytes());
}
};
//消费者在指定的队列上消费
channel.basicConsume(queueName, true, consumer);
}
}