====== 快速使用MQTT iOS版 SDK实现消息收发 ======
本文介绍快速使用 MQTT iOS版SDK 实现MQTT客户端消息的自收自发。
=====1. 前提条件=====
==== 1.1 部署iOS开发环境 ====
* 下载安装[[https://developer.apple.com/cn/support/xcode|xcode]]。
* 下载安装[[https://www.jianshu.com/p/fb7f533c39fc|cocoapods]],本文以cocoapods为例。
==== 1.2 导入项目依赖 ====
在项目的podfile文件中设置如下:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
pod 'MQTTClient'
pod 'AFNetworking'
pod 'MBProgressHUD'
pod 'Masonry'
pod 'MJRefresh'
pod 'YYModel'
target 'MQTTChat' do
end
===== 2. 实现流程 =====
==== 2.1 获取初始化信息 ====
登录console后台 \\
1.点击菜单栏【MQTT】->【服务概览】->【服务配置】,获取「连接地址」、「连接端口」、「AppID」以「及REST API地址」等信息。 \\
注:clientID由两部分组成,组织形式为“deviceID@AppID”,deviceID由用户自定义,AppID见【服务配置】。 \\
示例:正确的clientID格式为:“device001@aitbj0”; \\
2.点击菜单栏【应用概览】->【应用详情】->【开发者ID】,获取「Client ID」与「ClientSecret」信息。 \\
3.初始化代码
self.rootTopic = @"t1";
// appID 通过console后台[MQTT]->[服务概览]->[服务配置]下[AppID]获取
self.appId = @"ff6sc0";
//环信MQTT服务器地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[连接地址]获取
self.host = @"ff6sc0.cn1.mqtt.chat";
//环信MQTT REST API地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[REST API地址]获取
self.restapi = @"https://api.cn1.mqtt.chat/app/ff6sc0";
//开发者ID 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ Client ID]获取
self.appClientId = @"YXA67-uKaalmThCOut6Q8uPLSg";
// 开发者密钥 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ ClientSecret]获取
self.appClientSecret = @"YXA63CFpMQFai4MdTDdGN92BBoG6_6g";
// 协议服务端口 通过console后台[MQTT]->[服务概览]->[服务配置]下[连接端口]获取
self.port = 1883;
self.qos = 0;
self.tls = 0;
// 自定义deviceID
self.deviceId = [UIDevice currentDevice].identifierForVendor.UUIDString;
//开发者ID 通过console后台[应用概览]->[应用详情]->[开发者ID]下[ Client ID]获取
self.clientId = [NSString stringWithFormat:@"%@@%@",self.deviceId,self.appId];
{{:playground:message:setting.jpg|}}
{{:playground:message:develop.jpg|}}
==== 2.2 获取token ====
//获取应用token
- (void)getAppTokenWithAppClientId:(NSString *)appClientId
appClientSecret:(NSString *)appClientSecret
completion:(void (^)(NSString *appToken,NSInteger expires))response {
//环信MQTT REST API地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[REST API地址]获取
NSString *urlString = [NSString stringWithFormat:@"%@/openapi/rm/app/token",self.restapi];
//初始化一个AFHTTPSessionManager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//设置请求体数据为json类型
manager.requestSerializer = [AFJSONRequestSerializer serializer];
//设置响应体数据为json类型
manager.responseSerializer = [AFJSONResponseSerializer serializer];
//请求体,参数(NSDictionary 类型)
NSDictionary *parameters = @{@"appClientId":appClientId,
@"appClientSecret":appClientSecret
};
__block NSString *token = @"";
[manager POST:urlString
parameters:parameters
headers:@{}
progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:&error];
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
NSLog(@"%s jsonDic:%@",__func__,jsonDic);
NSDictionary *body = jsonDic[@"body"];
token = body[@"access_token"];
NSInteger expire_in = [body[@"expires_in"] integerValue];
response(token,expire_in);
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%s error:%@",__func__,error.debugDescription);
response(token,0);
}];
}
//获取用户token
- (void)getUserTokenWithUsername:(NSString *)username
appToken:(NSString *)appToken
clientId:(NSString *)clientId
expires:(NSInteger)expires
completion:(void (^)(NSString *userToken))response {
//环信MQTT REST API地址 通过console后台[MQTT]->[服务概览]->[服务配置]下[REST API地址]获取
NSString *urlString = [NSString stringWithFormat:@"%@/openapi/rm/user/token",self.restapi];
//初始化一个AFHTTPSessionManager
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//设置请求体数据为json类型
manager.requestSerializer = [AFJSONRequestSerializer serializer];
//设置响应体数据为json类型
manager.responseSerializer = [AFJSONResponseSerializer serializer];
//请求体,参数(NSDictionary 类型)
NSDictionary *parameters = @{
@"username":username,
@"expires_in":@(expires),//过期时间,单位为秒,默认为3天,如需调整,可提工单调整
@"cid":clientId
};
NSLog(@"%s\n urlString:%@\n parameters:%@\n",__func__,urlString,parameters);
__block NSString *token = @"";
[manager POST:urlString
parameters:parameters
headers:@{@"Authorization":appToken}
progress:nil
success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:&error];
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
NSLog(@"%s jsonDic:%@",__func__,jsonDic);
NSDictionary *body = jsonDic[@"body"];
token = body[@"access_token"];
response(token);
}
failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%s error:%@",__func__,error.debugDescription);
response(token);
}];
}
==== 2.3 连接服务器 ====
配置连接密码、cleansession标志、心跳间隔、超时时间等信息,调用connect()函数连接至环信MQTT消息云。
// 从console管理平台获取连接地址
[self.manager connectTo:self.host
port:self.port
tls:self.tls
keepalive:45
clean:true
auth:true
user:userName
pass:userToken
will:false
willTopic:nil
willMsg:nil
willQos:MQTTQosLevelAtMostOnce
willRetainFlag:false
withClientId:self.clientId
securityPolicy:nil
certificates:nil
protocolLevel:MQTTProtocolVersion50
connectHandler:^(NSError *error) {
}];
==== 2.4 订阅(subscribe) ====
=== 2.4.1 订阅主题&取消订阅主题 ===
当客户端成功连接环信MQTT消息云后,通过设置subscriptions参数值实现订阅主题与取消订阅主题 。当subscriptions非空时,订阅主题;当subscriptions为空时,取消订阅主题;
/**
订阅主题
格式为 xxx/xxx/xxx 可以为多级话题 @{@"xxx/xxx/xxx...":@(1)}
qos定义{ 0: 最多一次,1:至少一次 2:仅一次}
*/
self.manager.subscriptions = @{[NSString stringWithFormat:@"%@/IOS", self.rootTopic]:@(self.qos),[NSString stringWithFormat:@"%@/IOS_TestToic", self.rootTopic]:@(1)};
/**
取消订阅主题
*/
self.manager.subscriptions = @{};
=== 2.4.2 接收消息 ===
接收从服务器接受订阅消息。
/*
* MQTTSessionManagerDelegate
*/
- (void)handleMessage:(NSData *)data onTopic:(NSString *)topic retained:(BOOL)retained {
/*
* MQTTClient: process received message
*/
NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[self.receiveMsgs insertObject:[NSString stringWithFormat:@"RecvMsg from Topic: %@ Body: %@", topic, dataString] atIndex:0];
[self.tableView reloadData];
}
==== 2.5 发布消息(publish) ====
向指定topic发送消息
- (void)send {
/*
* MQTTClient: send data to broker
*/
[self.manager sendData:[self.messageTextField.text dataUsingEncoding:NSUTF8StringEncoding]
topic:[NSString stringWithFormat:@"%@/%@",
self.rootTopic,
@"IOS"]//此处设置多级子topic
qos:self.qos
retain:FALSE];
}
==== 2.6 断开连接 ====
MQTT client发送断开连接请求。
/*
* 断开连接
*/
- (void)disConnect {
[self.manager disconnectWithDisconnectHandler:^(NSError *error) {
}];
self.manager.subscriptions = @{};
}
==== 2.7 重新连接 ====
MQTT client发送重新连接请求。
/*
* 重新连接
*/
- (void)connect {
[self.manager connectToLast:^(NSError *error) {
}];
}
===== 3. 更多信息 =====
* 完整demo示例,请参见[[https://github.com/jinliang04551/MQTTChatDemo.git|demo下载]]。
* 目前MQTT客户端支持多种语言,请参见 [[http://docs-im.easemob.com/playground/message/sdkdownload|SDK下载]]。
* 如果您在使用MQTT服务中,有任何疑问和建议,欢迎您[[http://docs-im.easemob.com/playground/message/msgcontact|联系我们]]。