第一步:安装
目前,使用的是Pod生成的MQTTClient第三方库,直接下载就行 pod 'MQTTClient’
第二步:绑定
绑定前需要设置几个属性,主要有:
帐号、密码、clientId、ip、端口。
其次,还要注意这个库是没有连接中断自动重连的。所以需要监听他的状态。
#pragma mark - 绑定
- (void)bindWithUserName:(NSString *)username password:(NSString *)password cliendId:(NSString *)cliendId isSSL:(BOOL)isSSL{
self.username = username;
self.password = password;
self.cliendId = cliendId;
self.mySession = [[MQTTSession alloc]initWithClientId:self.cliendId userName:self.username password:self.password keepAlive:60 cleanSession:YES will:NO willTopic:nil willMsg:nil willQoS:MQTTQosLevelAtLeastOnce willRetainFlag:NO protocolLevel:4 queue:dispatch_get_main_queue() securityPolicy:[self customSecurityPolicy] certificates:nil];
self.isDiscontent = NO;
self.mySession.delegate = self;
[self.mySession connectToHost:AddressOfMQTTServer port:self.isSSL?PortOfMQTTServerWithSSL:PortOfMQTTServer usingSSL:isSSL];
[self.mySession addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}
- (MQTTSSLSecurityPolicy *)customSecurityPolicy
{
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"crt"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
MQTTSSLSecurityPolicy *securityPolicy = [MQTTSSLSecurityPolicy policyWithPinningMode:MQTTSSLPinningModeNone];
securityPolicy.allowInvalidCertificates = YES;
securityPolicy.validatesCertificateChain = YES;
securityPolicy.validatesDomainName = NO;
securityPolicy.pinnedCertificates = @[certData];
return securityPolicy;
}
当绑定完成之后,会打印出以下的信息。
第三步:设置断线重连
#pragma mark ---- 状态
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
switch (self.mySession.status) {
case MQTTSessionStatusClosed:
NSLog(@"连接关闭");
if (!self.isDiscontent) [self.mySession connect]; //这个是为了区分是主动断开还是被动断开。
break;
case MQTTSessionStatusConnected:
NSLog(@"连接成功");
[self subscribeTopicInArray];//这个是为了避免有部分订阅命令再连接完成前发送,导致订阅失败。
break;
case MQTTSessionStatusConnecting:
NSLog(@"连接中");
break;
case MQTTSessionStatusError:
NSLog(@"连接错误");
break;
case MQTTSessionStatusDisconnecting:
NSLog(@"正在断开连接");
default:
break;
}
}
第四步:订阅命令
#pragma mark - 订阅
- (void)subscribeTopic:(NSString *)topic {
if (self.mySession.status != MQTTSessionStatusConnected && ![self.subArray containsObject:topic]) {
[self.subArray addObject:topic];
return;
}
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self.mySession subscribeToTopic:topic atLevel:MQTTQosLevelAtLeastOnce subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
if (error) {
NSLog(@"subscribeTopic failed ----- topic = %@ \n %@",topic,error.localizedDescription);
[weakSelf.subArray addObject:topic];
[weakSelf subscribeTopicInArray];
} else {
if ([weakSelf.subArray containsObject:topic]) {
[weakSelf.subArray removeObject:topic];
}
NSLog(@"subscribeTopic sucessfull 成功! topic = %@ \n %@",topic,gQoss);
}
}];
});
});
}
取消订阅
#pragma mark - 取消订阅
- (void)unsubscribeTopic:(NSString *)topic {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self.mySession unsubscribeTopic:topic unsubscribeHandler:^(NSError *error) {
if (error) {
NSLog(@"unsubscribeTopic failed ----- topic = %@ \n %@",topic,error.localizedDescription);
} else {
NSLog(@"unsubscribeTopic sucessfull 成功! topic = %@ ",topic);
}
}];
});
});
}
发布消息
#pragma mark - 发布消息
- (void)sendDataToTopic:(NSString *)topic dict:(NSDictionary *)dict {
[self.mySession publishJson:dict onTopic:topic];
}
数据接收回调
#pragma mark MQTTSessionDelegate
- (void)newMessage:(MQTTSession *)session data:(NSData *)data onTopic:(NSString *)topic qos:(MQTTQosLevel)qos retained:(BOOL)retained mid:(unsigned int)mid {
NSLog(@"thl ----- data = %@ \n -------- topic:%@ --------- \n",data,topic);
if (self.delegate && [self.delegate respondsToSelector:@selector(MQTTClientModel_newMessage:data:onTopic:qos:retained:mid:)]) {
[self.delegate MQTTClientModel_newMessage:session data:data onTopic:topic qos:qos retained:retained mid:mid];
}
}
主动断开
- (void)disconnect {
[self.mySession removeObserver:self forKeyPath:@"status"];
self.isDiscontent = YES;
[self.mySession disconnect];
}
扩展(阿里云)
MQ
https://help.aliyun.com/document_detail/29532.html?spm=a2c4g.11174283.6.541.188d5793ebOGyb
接入MTQQ示例
https://help.aliyun.com/document_detail/47755.html?spm=5176.doc42420.6.637.WOPRPQ