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