MQTT协议是为大量计算能力有限,且工作在低带宽、不可靠的网络的远程传感器和控制设备通讯而设计的协议,它具有以下主要的几项特性:
1、使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合;
2、对负载内容屏蔽的消息传输;
3、使用 TCP/IP 提供网络连接;
4、有三种消息发布服务质量:qos
“至多一次”,消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。
“至少一次”,确保消息到达,但消息重复可能会发生。
“只有一次”,确保消息到达一次。这一级别可用于如下情况,在计费系统中,消息重复或丢失会导致不正确的结果。
5、小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量;
6、使用 Last Will 和 Testament 特性通知有关各方客户端异常中断的机制;
mqtt基于订阅者模型架构,客户端如果互相通信,必须在同一订阅主题下,即都订阅了同一个topic,客户端之间是没办法直接通讯的。订阅模型显而易见的好处是群发消息的话只需要发布到topic,所有订阅了这个topic的客户端就可以接收到消息了。
发送消息必须发送到某个topic,重点说明的是不管客户端是否订阅了该topic都可以向topic发送了消息,还有如果客户端订阅了该主题,那么自己发送的消息也会接收到。
// ViewController.m
// MQTT 再次测试
#import "ViewController.h"
#import <MQTTClient.h>
#define kMQTTServerHost @"192.168.1.4"
//#define kMQTTServerHost @"iot.eclipse.org"
@interface ViewController ()<MQTTSessionDelegate>
@property (nonatomic,strong) MQTTSession *session;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MQTTCFSocketTransport *transport = [[MQTTCFSocketTransport alloc] init]; // 初始化对象
transport.host = kMQTTServerHost; // 设置MQTT 服务器的地址
transport.port = 1883; // 设置MQTT服务器的端口 (默认是1883,可以和后台协商)
MQTTSession *session = [[MQTTSession alloc] init]; // 初始化 MQTTSession 对象
session.transport = transport; // 给mySession 对象设置基本信息
session.delegate=self; // 设置session的代理为self <记得准守协议>
[session connectAndWaitTimeout:30]; // 设定超时时长 如果超时则认为连接失败,如果设为0则表示连接成功
self.session = session;
/**
* 订阅主题 正如我们在第一篇博文所说的,MQTT协议是一个发布/订阅式的协议,所以在创建和连接完成后,我们就开始订阅主题。
* Qos : "服务质量"。QoS是网络的一种安全机制, 是用来解决网络延迟和阻塞等问题的一种技术
*/
[session subscribeToTopic:@"test" atLevel:2 subscribeHandler:^(NSError *error, NSArray<NSNumber *> *gQoss) {
if (error) {
NSLog(@"Subscription failed %@", error.localizedDescription);
}else{
NSLog(@"Subscription sucessfull! Granted Qos: %@", gQoss);
}
}];
}
/**
* 收到消息
*/
-(void)newMessage:(MQTTSession *)session data:(NSData *)data onTopic:(NSString *)topic qos:(MQTTQosLevel)qos retained:(BOOL)retained mid:(unsigned int)mid{
// 这个是代理回调方法,接收到的数据可以在这里进行处理.
NSLog(@"data===%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
NSLog(@"topic===%@",topic);
NSLog(@"qos==%hhu",qos);
NSLog(@"mid===%u",mid);
}
/**
* 发布消息
*
* @param data 你要发送的数据
* @param onTopic 哪个主题发送数据,
* @param retain retain如果是 YES, 数据会被存储在服务器 直到下一条retain也为YES的数据传入就会复写
* @param qos 三种消息等级
*/
-(void)sendMessage:(NSData *)data toPic:(NSString *)onTopic retain:(BOOL)retain qos:(MQTTQosLevel)level{
[self.session publishAndWaitData:data onTopic:onTopic retain:retain qos:level];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end