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


一. MQTT

一個物聯網項目中用到了MQTT協議, 可以用來做設備與軟件之間的互通.

MQTT: 即時通訊協議, 傳輸層協議

二. 常用:

1.MQTTKit(已經不維護了)

2.MQTTClient

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

b.訂閱主題(可以訂閱多個主題)

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

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

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

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

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

四. 代碼:

#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"];


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM