一. 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"];