1. 程式人生 > >iOS MQTT使用案例 (斷線重連)

iOS MQTT使用案例 (斷線重連)

iOS MQTT使用案例 (斷線重連)

參考了 iOS MQTT—-MQTTClient實戰-看這篇的就夠了 大神寫的這篇

git: MQTT-Client-Framework

介紹啥的看百度,上面大神寫的就行了,直接上乾貨。

安裝:

pod 'MQTTClient'

建立一個單例管理類來處理MQTT有關操作

匯入:
#import<MQTTClient/MQTTClient>

MQTTSession初始化:

- (MQTTSession *)session {
    if (_session == nil) {
        MQTTCFSocketTransport *transport = [MQTTCFSocketTransport new];
transport.host = kMQTTHost; transport.port = kMQTTPort; _session = [MQTTSession new]; _session.transport = transport; _session.delegate = self; _session.userName = kMQTTUserName; _session.password = kMQTTPsw; // _session.willQoS = 1; _session.clientId
= [NSUUID UUID].UUIDString; // 唯一標識 } return _session; }

管理類API:

 - (void)connect;

 - (void)subscribeTopic:(NSString *)topicUrl;

 - (void)unsubscribeTopic:(NSString *)topicUrl;

 - (void)logoutAction;

  • connect
- (void)connect {
     // 是否需要斷開連線標識
    _shouldCloseConnection = NO
; [self.session connectAndWaitTimeout:1]; // 似乎不是非同步執行 }
  • subscribeTopic && unsubscribeTopic
- (void)subscribeTopic:(NSString *)topicUrl {
    /* 儲存toppicUrl 用於重連 */
     ... 
    [MQTTHelper subscribeTopicWithSesion:self.session topic:topicUrl];
}
- (void)unsubscribeTopic:(NSString *)topicUrl {
    /* 刪除儲存的 toppicUrl */
     ... 
    [MQTTHelper unsubscribeTopicWithSesion:self.session topic:topicUrl];
}
  • logoutAction
    取消所有訂閱,關閉連線(我這裡是退出登入時用到)
- (void)logoutAction {
    _shouldCloseConnection = YES; // 不需要斷線重連

    [self.session unsubscribeTopics:self.topicUrls unsubscribeHandler:^(NSError *error) {
        [self.topicUrls removeAllObjects];
    }]; // 取消訂閱所有topic
    [self.session disconnect];
    [self.session close];

    self.session = nil;
}

訂閱 及 取消訂閱 類方法

+ (void)subscribeTopicWithSesion:(MQTTSession *)session topic:(NSString *)topicUrl {
    dispatch_async(dispatch_get_main_queue(), ^{
        [session subscribeToTopic:topicUrl atLevel:MQTTQosLevelAtLeastOnce subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
            if (error) {
                DLog(@"=*=*=*=*=*= Subscribe to topic fail =*=*=*=*=*=");
            } else {
                DLog(@"=*=*=*=*=*= Subscribe to topic success=*=*=*=*=*=\nGranted Qoss:\n%@", gQoss);
            }
        }];
    });
}

+ (void)unsubscribeTopicWithSesion:(MQTTSession *)session topic:(NSString *)topicUrl {
    [session unsubscribeTopic:topicUrl unsubscribeHandler:^(NSError *error) {
        if (error) {
            DLog(@"=*=*=*=*=*= Unsubscribe topic fail =*=*=*=*=*=");
        } else {
            DLog(@"=*=*=*=*=*= Unsubscribe topic success=*=*=*=*=*=");
        }
    }];
}

MQTTSessionDelegate

// 訂閱訊息資料回撥
- (void)newMessage:(MQTTSession *)session data:(NSData *)data onTopic:(NSString *)topic qos:(MQTTQosLevel)qos retained:(BOOL)retained mid:(unsigned int)mid {
//    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    MQTTEventModel *model = [MQTTEventModel mj_objectWithKeyValues:data]; // MJExtension解析

    /* 該幹嘛幹嘛 */
}
// 連線成功
- (void)connected:(MQTTSession *)session {
    if (_shouldConnct == YES) { // 需要斷線重連
        [MQTTHelper subscribeTopicWithSesion:session topic:self.topicUrls.lastObject];
        _shouldConnct = NO;
    }
}
// 連線斷開
- (void)connectionClosed:(MQTTSession *)session {
    if ( _shouldCloseConnection == NO) { // 如果是斷線的情況
        _shouldConnct = YES; // 則需要重連
        [session connect];
    }
}