长连接通道SDK,提供IoT业务协议封装的云端数据下行能力,为App提供订阅、发布消息的能力和支持请求响应模型。
依赖SDK | 概述 |
日志 | 基础依赖SDK,提供客户端统一日志打印,日志等级控制,分模块日志隔离等能力。 |
API 通道 | 提供API通道能力,和基础环境配置信息。 |
初始化
初始化的操作请参见SDK初始化。
使用说明
SDK封装了上行RPC请求、订阅、取消订阅等接口,详细接口参见长连接服务。
SDK中描述的Topic都是简短的Topic。例如完整的上行请求Topic:/sys/{productKey}/{deviceName}/app/up/test/publish。
上行请求SDK内部会判断补齐/sys/{productKey}/{deviceName}/app/up/,在调用SDK入参的时候只需要输入/test/publish即可。
对应的下行Topic,例如完整的设备状态变化下行Topic是/sys/{productKey}/{deviceName}/app/down/things/status。SDK回调里面只会露出/things/status,自动截断掉/sys/{productKey}/{deviceName}/app/down前缀。
业务请求响应模型
这个接口实际上是封装了一个Remote Procedure Call的过程。我以用户账号绑定通道的示例来说明内部逻辑:用户账号绑定通道的Topic为:/sys/{productKey}/{deviceName}/app/up/account/bind。
在向这个Topic发布数据前,先订阅这个Topic对应的Reply Topic,其格式如下所示 /sys/{productKey}/{deviceName}/app/down/account/bind_reply。订阅成功后才开始发布数据,IoT用户中心在收到SDK 发布到/sys/{productKey}/{deviceName}/app/up/account/bind这个Topic的数据后,完成账号绑定的业务逻辑后,会往/sys/{productKey}/{deviceName}/app/down/account/bind_reply这个Topic发布响应数据。SDK在收到这个reply Topic的数据后,将响应结果通过respHandler回调给用户,从而完成整个业务逻辑。
#import <AlinkAppExpress/LKAppExpress.h>
//由于长连接通道 SDK,会在内部逻辑中补齐 '/sys/{productKey}/{deviceName}/app/up' 部分,
//所以使用者在这个 API 时,只要传这一段的后边部分即 '/account/bind' 即可了。
[[LKAppExpress sharedInstance] invokeWithTopic : @"/account/bind" opts:nil params:@{@"iotToken":iotToken}
respHandler:^(LKAppExpResponse * _Nonnull response) {
LKAELogDebug(@"bindAccount result : %@", response);
}];
订阅Topic
长连接通道SDK,采用MQTT协议,基于订阅/发布模型设计。订阅某个Topic后,当其他服务或者终端往这个Topic发布消息时,便能收到消息。下边以订阅用户所绑定设备属性变化的Topic为例。
Topic全路径为:/sys/{productKey}/{deviceName}/app/down/thing/properties。由于长连接通道 SDK,会在内部逻辑中补齐/sys/{productKey}/{deviceName}/app/down部分,所以使用者在调用订阅Topic API 时,只要整个Topic 的后边部分即/thing/properties即可。其他Topic依次类推。
#import <AlinkAppExpress/LKAppExpress.h>
//以订阅用户所绑定的设备属性变化事件为例,详细的使用说明请参考 api reference
[[LKAppExpress sharedInstance]subscribe:@"/thing/properties" complete:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
[_tipsLabel setText:@"订阅成功"];
} else {
[_tipsLabel setText:@"订阅失败"];
}
});
}];
取消订阅Topic
取消订阅是订阅的逆过程,二者遵循同样的Topic规则。仍然以取消订阅用户所绑定设备属性变化的Topic为例。
#import <AlinkAppExpress/LKAppExpress.h>
// 详细的使用说明请参考 api reference
[[LKAppExpress sharedInstance]unsubscribe:@"/thing/properties" complete:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
[_tipsLabel setText:@"取消订阅成功"];
} else {
[_tipsLabel setText:@"取消订阅失败"];
}
});
}];
Publish数据
长连接通道SDK基于订阅/发布模型设计。既可以订阅Topic,也可以往某个Topic发布数据。下边以往Topic:/sys/{productKey}/{deviceName}/app/up/test/publish发送数据为例。
由于长连接通道SDK,会在内部逻辑中补齐/sys/{productKey}/{deviceName}/app/up部分,所以使用者在调用Publish数据API时,只要传这一段的后边部分即/test/publish即可。
#import <AlinkAppExpress/LKAppExpress.h>
NSString * text = @"{\"input\":\"Hello World\"}";
NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];
if (data == nil) {
return;
}
NSError *error;
NSDictionary *params = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
if (error) {
return;
}
[[LKAppExpress sharedInstance]publish:@"/test/publish" params:params
complete:^(NSError * _Nonnull error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
[_tipsLabel setText:@"publish成功"];
} else {
[_tipsLabel setText:@"publish失败"];
}
});
}];
注册下行Listener
注册下行Listener,才能接收到订阅过的Topic数据,参见长链接服务消息下行API。
#import <AlinkAppExpress/LKAppExpress.h>
@interface TestDownstreamListener : NSObject <LKAppExpDownListener>
@end
@implementation TestDownstreamListener
- (void)onDownstream:(NSString * _Nonnull)topic data:(id _Nullable)data {
NSLog(@"onDownstream topic : %@", topic);
NSLog(@"onDownstream data : %@", data);
NSDictionary * replyDict = nil;
if ([data isKindOfClass:[NSString class]]) {
NSData * replyData = [data dataUsingEncoding:NSUTF8StringEncoding];
replyDict = [NSJSONSerialization JSONObjectWithData:replyData options:NSJSONReadingMutableLeaves error:nil];
} else if ([data isKindOfClass:[NSDictionary class]]) {
replyDict = data;
}
if (replyDict == nil) {
return;
}
}
- (BOOL)shouldHandle:(NSString * _Nonnull)topic {
if ([topic isEqualToString:@"/thing/properties"]) {
return YES;//返回YES,说明对此topic感兴趣,SDK会调用[listener onDownstream:data:]
}
return NO;
}
@end
self.testListner = [TestDownstreamListener new];//sdk不会strong持有此listener,开发者自己保证listener不被释放.
[[LKAppExpress sharedInstance]addDownStreamListener:YES listener:self.testListner]
解绑长连接通道与账号
在初始化时,已实现长连接通道与账号的绑定,此时如果您需要解绑长连接通道与账号,参照以下代码执行。
如需解绑长连接通道跟用户账号的绑定,请在账号登出前操作,否则会导致解绑失败。
#import <AlinkAppExpress/LKAppExpress.h>
#import <IMSAuthentication/IMSCredentialManager.h>
#pragma mark - 取消长连接通道关联
NSString *topic = @"/account/unbind";
[[LKAppExpress sharedInstance] invokeWithTopic:topic opts:nil params:@{} respHandler:^(LKAppExpResponse * _Nonnull response) {
if (![response successed]) {
IMSLifeLogVerbose(@"解绑长连接推送失败");
}
}];