iOS開發--MQTT實時處理數據

一. MQTT

一個物聯網項目中用到了MQTT協議, 能夠用來作設備與軟件之間的互通.json

MQTT: 即時通信協議, 傳輸層協議服務器

二. 經常使用:

1.MQTTKit(已經不維護了)session

2.MQTTClientide

a.設置地址端口, 帳號密碼等基本信息spa

b.訂閱主題(能夠訂閱多個主題)代理

c.實現代理回調方法(處理數據)code

三. 三種消息傳輸方式:(看狀況使用)

a.至多一次 (會發生消息丟失或重複)server

b.至少一次 (確保消息到達, 會發生消息重複)blog

c.只有一次 (確保消息到達一次)ip

四. 代碼:

#import <MQTTClient/MQTTClient.h>
#import <MQTTClient/MQTTSessionManager.h>

配置基本信息

- (void)setParameterWithManager
{
    /**
     host: 服務器地址
     port: 服務器端口
     tls:  是否使用tls協議,mosca是支持tls的,若是使用了要設置成true
     keepalive: 心跳時間,單位秒,每隔固定時間發送心跳包, 心跳間隔不得大於120s
     clean: session是否清除,這個須要注意,若是是false,表明保持登陸,若是客戶端離線了再次登陸就能夠接收到離線消息
     auth: 是否使用登陸驗證
     user: 用戶名
     pass: 密碼
     willTopic: 訂閱主題
     willMsg: 自定義的離線消息
     willQos: 接收離線消息的級別
     clientId: 客戶端id,須要特別指出的是這個id須要全局惟一,由於服務端是根據這個來區分不一樣的客戶端的,默認狀況下一個id登陸後,假若有另外的鏈接以這個id登陸,上一個鏈接會被踢下線, 我使用的設備UUID
     */
    NSString *clientId = [UIDevice currentDevice].identifierForVendor.UUIDString;
    self.sessionManager = [[MQTTSessionManager alloc] init];
    [self.sessionManager connectTo:MQTTHOST
                              port:MQTTPORT
                               tls:false
                         keepalive:60  //心跳間隔不得大於120s
                             clean:true
                              auth:true
                              user:MQTTUSERNAME
                              pass:MQTTPASSWORD
                              will:false
                         willTopic:nil
                           willMsg:nil
                           willQos:0
                    willRetainFlag:false
                      withClientId:clientId];
    self.sessionManager.delegate = self;

    // 添加監聽狀態觀察者
    [self.sessionManager addObserver:self
                          forKeyPath:@"state"
                             options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                             context:nil];
    // 訂閱主題    NSDictionary類型,Object 爲 QoS,key 爲 Topic
    self.sessionManager.subscriptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:MQTTQosLevelExactlyOnce] forKey:@"你要訂閱的主題(和後臺商量好)"];
}

 

監聽鏈接狀態

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    switch (self.sessionManager.state) {
        case MQTTSessionManagerStateClosed:
            NSLog(@"鏈接已經關閉");
            break;
        case MQTTSessionManagerStateClosing:
            NSLog(@"鏈接正在關閉");
            break;
        case MQTTSessionManagerStateConnected:
            NSLog(@"已經鏈接");
            break;
        case MQTTSessionManagerStateConnecting:
            NSLog(@"正在鏈接中");
            break;
        case MQTTSessionManagerStateError: {
            NSString *errorCode = self.sessionManager.lastErrorCode.localizedDescription;
            NSLog(@"鏈接異常 ----- %@",errorCode);
        }
            break;
        case MQTTSessionManagerStateStarting:
            NSLog(@"開始鏈接");
            break;
        default:
            break;
    }
}

處理數據

// 實現MQTTSessionManagerDelegate代理方法,處理數據。
- (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained
{
    NSLog(@"主題:%@",topic);
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSData * newData = [dataString dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:newData options:NSJSONReadingMutableLeaves error:nil];
    NSLog(@"數據:%@",jsonDict);
}

最後不要忘記移除觀察者, 不然程序會崩潰

[self.sessionManager removeObserver:self forKeyPath:@"state"];
相關文章
相關標籤/搜索