发送到 主题交换机的消息不能具有任意的 routingKey ,他必须由点分隔的单词列表,单词可以是任何内容,但通过他们指定与消息相关的一些功能。路由秘钥中可以包含任意数量的单词,最多可达到255个字节。
绑定秘钥也必须采取相同的形式,主题交换机背后的逻辑类似于 直连交换机。使用特定路由秘钥发送的消息将被传递到与匹配绑定秘钥绑定的所有队列。
在这例子中,我们将发送所有描述动物的消息。消息将与包含三个单词(两个点)的路由键一起发送,路由键中的第一个单词将描述速度,第二个将描述颜色,第三个将描述物种:speed.color.species
我们创建了三个绑定:Q1绑定了 绑定秘钥为:.orange. ,Q2绑定了 绑定秘钥为:..rabbit 和 lazy.#
这些绑定可以概括为:
Q1对所有橙色的动物感兴趣
Q2对兔子的一切感兴趣,以及懒惰动物的一切。
路由秘钥设置为“ quick.orange.rabbit ”的消息将传递到两个队列去。
路由秘钥设置为“ lazy.orange.elephant ”的消息也将会传递到两个队列去。
路由秘钥设置为“ quick.orange.fox ”的消息会传递到第一个Q1的队列去。
路由秘钥设置为“ lazy.brown.fox ”的消息会传到第二个Q2的队列去。
路由秘钥设置为“ lazy.pink.rabbit ”的消息也会传递到第二个Q2的队列去,即使它匹配了两个绑定。
路由秘钥设置为“ quick.brown.fox ”的消息不匹配任何绑定,它将被丢弃。
另一个路由秘钥设置为“ quick.orange.maie.rabbit ”的消息,也将会被丢弃。
路由秘钥设置为“ lazy.orange.maie.rabbit”,及时他有4个单词,也会匹配上Q2对列的绑定。
public class TopicsSend {
final static String EXCHANGE_NAME = "Topics_test";
static ConnectionUtil connUtil = new ConnectionUtil();
public static void main(String[] args) throws Exception {
Connection conn = connUtil.getConn();
Channel channel = conn.createChannel();
//声明交换机 指定direct直连类型
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
String message1 = "Exchange type topic, test error.test.info";
String severity = "error.test.info";
//发布到交换机
channel.basicPublish(EXCHANGE_NAME, severity, null, message1.getBytes());
System.out.println("绑定秘钥:"+severity+", 消息:"+message1);
String message2 = "Exchange type topic, test info.test.action";
String severity2 = "info.test.action";
//发布到交换机
channel.basicPublish(EXCHANGE_NAME, severity2, null, message2.getBytes());
System.out.println("绑定秘钥:"+severity2+", 消息:"+message2);
String message3 = "Exchange type topic, test warning.info.action";
String severity3 = "warning.info.action";
//发布到交换机
channel.basicPublish(EXCHANGE_NAME, severity3, null, message3.getBytes());
System.out.println("绑定秘钥:"+severity3+", 消息:"+message3);
// 关闭通道和连接
channel.close();
conn.close();
}
}
public class TopicsReceiver {
final static String EXCHANGE_NAME = "Topics_test";
static ConnectionUtil connUtil = new ConnectionUtil();
public static void main(String[] args) throws Exception {
Connection conn = connUtil.getConn();
Channel channel = conn.createChannel();
//声明交换机 指定direct直连类型
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
//获取临时队列名称
String queneName = channel.queueDeclare().getQueue();
//绑定队列 绑定秘钥 *.test.*
channel.queueBind(queneName, EXCHANGE_NAME, "*.test.*");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("接受类型:*.test.* , 路由秘钥:"+delivery.getEnvelope().getRoutingKey()+",接受消息: '" + message + "'");
};
channel.basicConsume(queneName, true, deliverCallback, consumerTag -> {});
}
}
public class RoutingReceiver2 {
final static String EXCHANG_NAME = "Topics_test";
static ConnectionUtil connUtil = new ConnectionUtil();
public static void main(String[] args) throws Exception {
Connection conn = connUtil.getConn();
Channel channel = conn.createChannel();
//声明交换机 指定direct直连类型
channel.exchangeDeclare(EXCHANG_NAME, "topic");
//获取临时队列名称
String queneName = channel.queueDeclare().getQueue();
//绑定队列 error.#
channel.queueBind(queneName, EXCHANG_NAME, "error.#");
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("接受类型:error.# , 路由秘钥:"+delivery.getEnvelope().getRoutingKey()+",接受消息: '" + message + "'");
};
channel.basicConsume(queneName, true, deliverCallback, consumerTag -> {});
}
}