MQTT(二)----- iOS使用
阿新 • • 發佈:2018-12-21
第一步:安裝
目前,使用的是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];
}