目录:
该系列文章预计包括:
前言:
这里的代码是从MQTTSessionManager为切入点进入的,所以下面的方法如果没有特殊描述都是从这个类然后进入内部。 主题 == topic文章中可能出现多次,大家自己转化一下。
正文:
当你连接成功之后,就要开始着手发布消息和订阅消息。在发布和订阅之前呢,首先你得要有一个主题(topic),不然你对谁发,一个topic可以被多次订阅,比如iOS设备订阅了,Android设备也订阅了,这个时候用任意一端设备发送消息,其他一端都可以收到。所以这里你首先要知道主题(一般问服务器要)。
在上一个文章中,假设你没有在创建的时候就传入topic,那么在发送数据之前你可以先订阅一下这个topic,如果发送成功了,会收到一样的消息(这里笔者之前是调试用的时候用,当然你也可以不用)。
主题的格式:标记:级别
啥意思呢?
比如你的主题叫: "ijk-dr-rec" 级别(qos)是:1
那么你给的参数就是:
OC: @{ @"ijk-dr-rec": @(1) }
Swift: ["ijk-dr-rec", NSNumber(value: 1)]
一般来说我们最少会有两个主题:一个主题用户发布数据,一个用于订阅信息
订阅主题:
通过对这个属性的赋值subscriptions,然后监听set方法,在set方法内部处理
- (void)setSubscriptions:(NSDictionary *)newSubscriptions {
// 判断连接上了没,没连接上就不订阅和取消订阅的操作
if (self.state == MQTTSessionManagerStateConnected) {
NSDictionary *currentSubscriptions = [self.effectiveSubscriptions copy];
// 拿到已有的topic,然后取消订阅
for (NSString *topicFilter in currentSubscriptions) {
if (!newSubscriptions[topicFilter]) {
__weak MQTTSessionManager *weakSelf = self;
/// 取消订阅
[self.session unsubscribeTopic:topicFilter unsubscribeHandler:^(NSError *error) {
// 如果取消成功了,就移除掉
MQTTSessionManager *strongSelf = weakSelf;
if (!error) {
/// 因为这里是异步的,所以锁起来了
[strongSelf.subscriptionLock lock];
NSMutableDictionary *newEffectiveSubscriptions = [strongSelf.subscriptions mutableCopy];
[newEffectiveSubscriptions removeObjectForKey:topicFilter];
strongSelf.effectiveSubscriptions = newEffectiveSubscriptions;
[strongSelf.subscriptionLock unlock];
}
}];
}
}
// 订阅新的主题,流程和上面一样,只不过一个是移除,一个是添加
for (NSString *topicFilter in newSubscriptions) {
if (!currentSubscriptions[topicFilter]) {
NSNumber *number = newSubscriptions[topicFilter];
MQTTQosLevel qos = number.unsignedIntValue;
__weak MQTTSessionManager *weakSelf = self;
[self.session subscribeToTopic:topicFilter atLevel:qos subscribeHandler:^(NSError *error, NSArray *gQoss) {
MQTTSessionManager *strongSelf = weakSelf;
if (!error) {
NSNumber *gQos = gQoss[0];
[strongSelf.subscriptionLock lock];
NSMutableDictionary *newEffectiveSubscriptions = [strongSelf.subscriptions mutableCopy];
newEffectiveSubscriptions[topicFilter] = gQos;
strongSelf.effectiveSubscriptions = newEffectiveSubscriptions;
[strongSelf.subscriptionLock unlock];
}
}];
}
}
}
// 把新的主题赋值给 internalSubscriptions
self.internalSubscriptions = newSubscriptions;
DDLogVerbose(@"MQTTSessionManager internalSubscriptions: %@", self.internalSubscriptions);
}
代码解释:
上面的方法中主要做的就是,取消订阅之前旧的主题,然后订阅新的主题,在把新的主题保存起来, 如果你的程序员中不能一开始就确定好主题数量,建议自己维护主题
发送消息:
终于到了这个令人愉快的时候, 调用- (UInt16)sendData:(NSData *)data topic:(NSString *)topic qos:(MQTTQosLevel)qos retain:(BOOL)retainFlag
- (UInt16)sendData:(NSData *)data topic:(NSString *)topic qos:(MQTTQosLevel)qos retain:(BOOL)retainFlag {
if (self.state != MQTTSessionManagerStateConnected) {
[self connectToLast:nil];
}
UInt16 msgId = [self.session publishData:data
onTopic