下載地址:https://github.com/ckrey/MQTT-Client-Framework(使用MQTTClientSDK,使用時候刪除無用的提示文件,MQTTClient.h文件導入的報錯修改下)
MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個設計得非常出色的傳輸層協議,在移動消息、物聯網、車聯網、智能硬件甚至能源勘探等領域有着廣泛的應用。非常適合在低帶寬、不可靠網絡、嵌入式設備上應用。該協議支持所有平台,也就是說不論什么平台都可以使用集成此協議,網上大多說該協議用於物聯網,有可能成為物聯網的重要組成部分。是一個即時通訊協議
自己構建
//MQTTStatus.h文件
// // MQTTStatus.h // MQTTSDKLearn // // Created by Vie on 2017/3/3. // Copyright © 2017年 Vie. All rights reserved. // #import <Foundation/Foundation.h> #import "MQTTClient.h" @interface MQTTStatus : NSObject //狀態 @property(nonatomic,assign) MQTTSessionEvent statusCode; //狀態信息 @property(nonatomic,copy) NSString *statusInfo; @end
//MQTTStatus.m文件
// // MQTTStatus.m // MQTTSDKLearn // // Created by Vie on 2017/3/3. // Copyright © 2017年 Vie. All rights reserved. // #import "MQTTStatus.h" @implementation MQTTStatus @end
//MQTTClientManagerDelegate.h文件
// // MQTTClientManagerDelegate.h // MQTTSDKLearn // // Created by Vie on 2017/3/3. // Copyright © 2017年 Vie. All rights reserved. // /** MQTTClientManager委托事件 */ #import "MQTTStatus.h" @protocol MQTTClientManagerDelegate <NSObject> @optional /** 連接狀態返回 @param status 錯誤碼和錯誤info */ -(void)didMQTTReceiveServerStatus:(MQTTStatus *)status; /** 服務器推送消息返回 @param topic 消息主題 @param dic 消息內容,JSON轉字典 */ -(void)messageTopic:(NSString *)topic data:(NSDictionary *)dic; /** 服務器推送消息返回 @param topic 消息主題 @param jsonStr 消息內容,JSON字符串 */ -(void)messageTopic:(NSString *)topic jsonStr:(NSString *)jsonStr; @end
//MQTTClientManager.h文件
// // MQTTClientManager.h // MQTTSDKLearn // // Created by Vie on 2017/3/3. // Copyright © 2017年 Vie. All rights reserved. // #import <Foundation/Foundation.h> @interface MQTTClientManager : NSObject /** 單例 @return self */ +(MQTTClientManager *)shareInstance; /** MQTT登陸,訂閱單個主題 @param ip 服務器ip @param port 服務器端口 @param userName 用戶名 @param password 密碼 @param topic 訂閱的主題,可以訂閱的主題與賬戶是相關聯的,例:@"mqtt/test" */ -(void)loginWithIp:(NSString *)ip port:(UInt16)port userName:(NSString *)userName password:(NSString *)password topic:(NSString *)topic; /** MQTT登陸,訂閱多個主題 @param ip 服務器ip @param port 服務器端口 @param userName 用戶名 @param password 密碼 @param topics 訂閱的主題,可以訂閱的主題與賬戶是相關聯的,例:@{@"mqtt/test":@"mqtt/test",@"mqtt/test1":@"mqtt/test1"} */ -(void)loginWithIp:(NSString *)ip port:(UInt16)port userName:(NSString *)userName password:(NSString *)password topics:(NSDictionary *)topics; /** 斷開連接,清空數據 */ -(void)close; /** 注冊代理 @param obj 需要實現代理的對象 */ -(void)registerDelegate:(id)obj; /** 解除代理 @param obj 需要接觸代理的對象 */ -(void)unRegisterDelegate:(id)obj; @end
//MQTTClientManager.m文件
// // MQTTClientManager.m // MQTTSDKLearn // // Created by Vie on 2017/3/3. // Copyright © 2017年 Vie. All rights reserved. // #import "MQTTClientManager.h" #import "MQTTClientManagerDelegate.h" #import "MQTTClient.h" #import <UIKit/UIDevice.h> #import "MQTTStatus.h" @interface MQTTClientManager ()<MQTTSessionDelegate> @property(nonatomic, weak) id<MQTTClientManagerDelegate> delegate;//代理 @property(nonatomic, strong) MQTTSession *mqttSession; @property(nonatomic, strong) MQTTCFSocketTransport *transport;//連接服務器屬性 @property(nonatomic, strong) NSString *ip;//服務器ip地址 @property(nonatomic) UInt16 port;//服務器ip地址 @property(nonatomic, strong) NSString *userName;//用戶名 @property(nonatomic, strong) NSString *password;//密碼 @property(nonatomic, strong) NSString *topic;//單個主題訂閱 @property(nonatomic, strong) NSDictionary *topics;//多個主題訂閱 @property(nonatomic, strong) MQTTStatus *mqttStatus;//連接服務器狀態 @end @implementation MQTTClientManager #pragma mark 懶加載 -(MQTTSession *)mqttSession{ if (!_mqttSession) { /*app包名+|iOS|+設備信息作為連接id確保唯一性*/ NSString *clientID=[NSString stringWithFormat:@"%@|iOS|%@",[[NSBundle mainBundle] bundleIdentifier],[UIDevice currentDevice].identifierForVendor.UUIDString]; NSLog(@"-----------------MQTT連接的ClientID-----------------%@",clientID); _mqttSession=[[MQTTSession alloc] initWithClientId:clientID]; } return _mqttSession; } -(MQTTCFSocketTransport *)transport{ if (!_transport) { _transport=[[MQTTCFSocketTransport alloc] init]; } return _transport; } -(MQTTStatus *)mqttStatus{ if (!_mqttStatus) { _mqttStatus=[[MQTTStatus alloc] init]; } return _mqttStatus; } #pragma mark 對外方法 /** 單例 @return self */ +(MQTTClientManager *)shareInstance{ static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance=[[self alloc] init]; }); return instance; } /** MQTT登陸,訂閱單個主題 @param ip 服務器ip @param port 服務器端口 @param userName 用戶名 @param password 密碼 @param topic 訂閱的主題,可以訂閱的主題與賬戶是相關聯的,例:@"mqtt/test" */ -(void)loginWithIp:(NSString *)ip port:(UInt16)port userName:(NSString *)userName password:(NSString *)password topic:(NSString *)topic{ self.topic=topic; [self loginWithIp:ip port:port userName:userName password:password]; } /** MQTT登陸,訂閱多個主題 @param ip 服務器ip @param port 服務器端口 @param userName 用戶名 @param password 密碼 @param topics 訂閱的主題,可以訂閱的主題與賬戶是相關聯的,例:@{@"mqtt/test":@"mqtt/test",@"mqtt/test1":@"mqtt/test1"} */ -(void)loginWithIp:(NSString *)ip port:(UInt16)port userName:(NSString *)userName password:(NSString *)password topics:(NSDictionary *)topics{ self.topics=topics; [self loginWithIp:ip port:port userName:userName password:password]; } -(void)loginWithIp:(NSString *)ip port:(UInt16)port userName:(NSString *)userName password:(NSString *)password { self.ip=ip; self.port=port; self.userName=userName; self.password=password; [self loginMQTT]; } /*實際登陸處理*/ -(void)loginMQTT{ /*設置ip和端口號*/ self.transport.host=_ip; self.transport.port=_port; /*設置MQTT賬號和密碼*/ self.mqttSession.transport=self.transport;//給MQTTSession對象設置基本信息 self.mqttSession.delegate=self;//設置代理 [self.mqttSession setUserName:_userName]; [self.mqttSession setPassword:_password]; //會話鏈接並設置超時時間 [self.mqttSession connectAndWaitTimeout:20]; } /** 斷開連接,清空數據 */ -(void)close{ [_mqttSession close]; _delegate=nil;//代理 _mqttSession=nil; _transport=nil;//連接服務器屬性 _ip=nil;//服務器ip地址 _port=0;//服務器ip地址 _userName=nil;//用戶名 _password=nil;//密碼 _topic=nil;//單個主題訂閱 _topics=nil;//多個主題訂閱 } /** 注冊代理 @param obj 需要實現代理的對象 */ -(void)registerDelegate:(id)obj{ self.delegate=obj; } /** 解除代理 @param obj 需要接觸代理的對象 */ -(void)unRegisterDelegate:(id)obj{ self.delegate=nil; } #pragma mark MQTTClientManagerDelegate /*連接成功回調*/ -(void)connected:(MQTTSession *)session{ NSLog(@"-----------------MQTT成功建立連接-----------------"); if (_topic) { NSLog(@"-----------------MQTT訂閱單個主題-----------------"); [self.mqttSession subscribeTopic:_topic]; }else if(_topics){ NSLog(@"-----------------MQTT訂閱多個個主題-----------------"); [self.mqttSession subscribeToTopics:_topics]; } } /*連接狀態回調*/ -(void)handleEvent:(MQTTSession *)session event:(MQTTSessionEvent)eventCode error:(NSError *)error{ NSDictionary *events = @{ @(MQTTSessionEventConnected): @"connected", @(MQTTSessionEventConnectionRefused): @"connection refused", @(MQTTSessionEventConnectionClosed): @"connection closed", @(MQTTSessionEventConnectionError): @"connection error", @(MQTTSessionEventProtocolError): @"protocoll error", @(MQTTSessionEventConnectionClosedByBroker): @"connection closed by broker" }; [self.mqttStatus setStatusCode:eventCode]; [self.mqttStatus setStatusInfo:[events objectForKey:@(eventCode)]]; if (self.delegate&&[self.delegate respondsToSelector:@selector(didMQTTReceiveServerStatus:)]) { [self.delegate didMQTTReceiveServerStatus:self.mqttStatus]; } NSLog(@"-----------------MQTT連接狀態%@-----------------",[events objectForKey:@(eventCode)]); } /*收到消息*/ -(void)newMessage:(MQTTSession *)session data:(NSData *)data onTopic:(NSString *)topic qos:(MQTTQosLevel)qos retained:(BOOL)retained mid:(unsigned int)mid{ NSString *jsonStr=[NSString stringWithUTF8String:data.bytes]; NSLog(@"-----------------MQTT收到消息主題:%@內容:%@",topic,jsonStr); NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; if (self.delegate&&[self.delegate respondsToSelector:@selector(messageTopic:data:)]) { [self.delegate messageTopic:topic data:dic]; } if (self.delegate&&[self.delegate respondsToSelector:@selector(messageTopic:jsonStr:)]) { [self.delegate messageTopic:topic jsonStr:jsonStr]; } } @end