前几天忙别的事,没时间写,现在补上。
在上一章中,我们集成了RMQClient,并进行了一些基础操作,这一章来讲讲广播模式接收多个消息。
有一种场景是,我发出一条消息,需要多个人收到,但我并不在乎是哪一些人收到。例如老板说,今天不用上班,那全公司的人就都收到了。
了解了基础需求后,我们开始干活儿。
一、接收方法
- (void)receive
{
RMQConnection * connection = [[RMQConnection alloc] initWithDelegate:[RMQConnectionDelegateLogger new]];
[connection start];
id<RMQChannel> channel = [connection createChannel];
//options 为声明属性,断开连接后自动删除
RMQQueue * queue = [channel queue:@"" options:RMQQueueDeclareAutoDelete];
RMQExchange * exchange = [channel fanout:self.exTF.text options:RMQExchangeDeclareAutoDelete];
[queue bind:exchange];
[queue subscribe:^(RMQMessage * _Nonnull message) {
NSLog(@"<二>收到消息:%@",[[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding]);
}];
}
说明:
-
[channel fanout:self.exTF.text options:RMQExchangeDeclareAutoDelete]
这行代码的意思是将通道与交换机使用self.exTF.text字段进行广播匹配,且在断开时自动删除该交换机。
在RabbitMQ中有4种匹配方式,分别是direct(完全匹配),fanout(广播匹配),topic(主题匹配),header(标题匹配)。
1.1 广播匹配,fanout
这种匹配方式,不需要考虑路由键(routingKey),它类似网络中的广播模式,将消息发送到所有与该exchange绑定的队列上,比如你在一个exchange上绑定了3个队列,分别是q1,q2,q3,你将一条消息发送给q1,那么q2和q3也将会收到。
这种匹配方式必须先绑定一个队列,如果你向一个没有绑定的队列发送了消息,那么这条消息将会被丢弃
1.2 完全匹配,direct
这种匹配方式需要考虑路由键(routingKey),它需要将一个队列绑定到交换机上,要求该消息与队列的一个routingKey完全匹配。如果一个队列接收到消息的时候,只有匹配了该routingKey的队列才会收到消息。比如,一个队列绑定到该交换机上,要求routingKey为"banana",那么则只有routingKey为banana的队列才能收到消息,既不会转发到banana.abc也不会转发到banana.abc.edf,也不会转发到apple上。
1.3 主题匹配,topic
这是一种按照通配符匹配的方式,它不能随意指定routingKey,它的格式为abc.或者abc.#样式的字符串,且长度不能超过255个字节,代表匹配一个单词,#号代表多个单词(或者0个),前者可以理解为精确匹配,后者可以理解为模糊匹配。
1.4 标题匹配,header
这是一种标题匹配模式,它不需要字符串类型的routingKey,而是采用键值对进行匹配。生产者在发送消息的时候设置一些键值对,消费者在绑定的时候设置一些键值对,两者匹配成功才能接收到消息。它有两种类型,一种是all,一种是any,all代表全部键值对匹配成功,any代表部分匹配成功。这两种类型在消费者端都必须采用"x-match"来定义。 - 在声明队列的时候,我没有给队列名,这是因为,我们需要一个临时队列,让生产者把消息发送到所有队列上,而不能指定一个队列。
二、发送方法
- (void)send
{
RMQConnection * connection = [[RMQConnection alloc] initWithDelegate:[RMQConnectionDelegateLogger new]];
[connection start];
id<RMQChannel> channel = [connection createChannel];
RMQExchange * exchange = [channel fanout:self.exTF.text options:RMQExchangeDeclareAutoDelete];
[exchange publish:[self.msgTF.text dataUsingEncoding:NSUTF8StringEncoding]];
[connection close];
}
说明:发送方法的匹配模式要和接收方法的匹配模式一样。
这一章结束。
附上DEMO地址。