iOS MQTTClient
2018-08-28 本文已影响152人
iOS104
1、简介:
MQTT 是IBM开发的一个即时通讯协议,有可能成为物联网的重要组成部分。该协议支持所有平台,几乎可以把所有联网物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议
2、特点:
MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:
-
1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
-
2、对负载内容屏蔽的消息传输;
-
3、使用 TCP/IP 提供网络连接;
-
4、有三种消息发布服务质量:
- “至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
- “至少一次”,确保消息到达,但消息重复可能会发生。
- “只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
-
5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
-
6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;
3、iOS MQTT 集成方案
三方库: MQTTClient
集成方式:pod 'MQTTClient'
主要功能:
- 1、登录接口
/**
host: 服务器地址
port: 服务器端口
tls: 是否使用tls协议,1883 NO 8883 YES
keepalive: 心跳时间,单位秒,每隔固定时间发送心跳包, 心跳间隔不得大于120s
clean: session是否清除,这个需要注意,如果是false,代表保持登录,如果客户端离线了再次登录就可以接收到离线消息
auth: 是否使用登录验证
user: 用户名
pass: 密码
willTopic: 订阅主题
willMsg: 自定义的离线消息
willQos: 接收离线消息的级别
clientId: 客户端id,需要特别指出的是这个id需要全局唯一,因为服务端是根据这个来区分不同的客户端的,默认情况下一个id登录后,假如有另外的连接以这个id登录,上一个连接会被踢下线, 我使用的session
*/
[sessionManager connectTo:port
port:1883
tls:false
keepalive:60 //心跳间隔不得大于120s
clean:true
auth:true
user:@"user"
pass:@"pass"
will:false
willTopic:nil
willMsg:nil
willQos:0
willRetainFlag:false
withClientId:clientId];
sessionManager.delegate = self;
self.sessionManager = sessionManager;
- 2、监控连接状态
// 添加监听状态观察者
[self.sessionManager addObserver:self
forKeyPath:@"state"
options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
context:nil];
- 3、 监听连接状态,进行相应处理
// 监听当前连接状态
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)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;
}
}
- 4、 接收消息
// 获取服务器返回数据
- (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained {
// 进行消息处理
}
- 5、 订阅和发送消息
// 订阅主题 NSDictionary类型,Object 为 QoS,key 为 Topic
self.sessionManager.subscriptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:MQTTQosLevelExactlyOnce] forKey:@"hello"];
// 发送消息 返回值msgid大于0代表发送成功
NSString *msg = @"hahaha";
UInt16 msgid = [self.sessionManager sendData:[msg dataUsingEncoding:NSUTF8StringEncoding] //要发送的消息体
topic:@"hello" //要往哪个topic发送消息
qos:1 //消息级别
retain:false];
遇到的问题:
1、订阅的类型,根据不同的维度去订阅,qos = 1
2、qos = 1,接受数据的时候数据去重工作
3、mqtt 断线重连,超时时间采用指数增长 3,6,12,24,48,48,48。。。
4、进入后台,程序结束任务前,close connected
5、根据服务端返回的数据确定登录的host,port,SSL
6、发送数据的加密
7、接受数据的解密