本文介绍如何进行Java Link SDK初始化,建立设备与物联网平台的连接。
前提条件
已创建产品和设备。具体操作,请参见创建产品和设备。
已获取设备的认证信息以及设备的接入域名。
背景信息
Java Link SDK仅支持设备密钥方式,进行设备身份认证,具体包括以下几种认证方式。
认证方式
注册方式
说明
认证方式
注册方式
说明
不涉及
每台设备烧录自己的设备证书(ProductKey、DeviceName和DeviceSecret)。
预注册
同一产品下设备烧录相同产品证书(ProductKey和ProductSecret)。
产品需开启动态注册功能。
设备通过动态注册获取DeviceSecret。
免预注册
同一产品下设备烧录相同产品证书(ProductKey和ProductSecret)。
产品需开启动态注册功能。
设备通过动态注册获取ClientID与DeviceToken的组合。
一型一密预注册和免预注册的区别,请参见预注册和免预注册的区别。
Java Link SDK中参数说明,请参见LinkKitInitParams。
一机一密
一机一密的设备认证方式的示例代码如下:
String productKey = "${YourProductKey}";
String deviceName = "${YourDeviceName}";
String deviceSecret = "${YourDeviceSecret}";
LinkKitInitParams params = new LinkKitInitParams();
final String TAG = "HelloWorld";
/**
* step 1: 设置MQTT初始化参数
*/
IoTMqttClientConfig config = new IoTMqttClientConfig();
MqttConfigure.mqttHost = "{YourInstanceId}.mqtt.iothub.aliyuncs.com:8883";
/*
*是否接受离线消息
*对应MQTT的cleanSession字段
*/
config.receiveOfflineMsg = false;
params.mqttClientConfig = config;
/**
* step 2: 设置初始化设备认证信息
*/
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.productKey = productKey;
deviceInfo.deviceName = deviceName;
deviceInfo.deviceSecret = deviceSecret;
params.deviceInfo = deviceInfo;
/**
* step 3: 设置设备的username, token和clientId
* 仅用于一型一密免预注册
* 默认关闭
*/
// MqttConfigure.deviceToken="${YourDeviceToken}";
// MqttConfigure.clientId="${YourClientId}";
LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
public void onError(AError aError) {
ALog.e(TAG, "Init Error error= "+aError);
}
public void onInitDone(InitResult initResult) {
ALog.i(TAG, "onInitDone result=" + initResult);
}
});
发起初始化请求后,如果返回
onInitDone
表示初始化成功,返回onError
表示初始化失败。初始化失败后,您可以根据业务需要,设置是否再次进行初始化,Java Link SDK不会自动尝试连接物联网平台。
初始化成功后,如果设备异常断开,Java Link SDK会自动重连。
动态注册
一型一密又称动态注册,用于向物联网平台获取设备的密钥,具体分为免预注册和预注册两种方式。使用该功能前,需要确保:
已在物联网平台创建产品并开启动态注册开关。
Demo的
deviceinfo
文件中的deviceSecret的值为空,productSecret不为空。请确保已执行下面示例代码中的step1、step2、step3。
动态注册成功或失败之后,需要断开当前的动态注册长连接,请参考示例代码的step4。
当前Demo支持的是一型一密预注册方式。您可参考示例代码中step 1的说明调整成一型一密免预注册方式。
为了您的设备安全,使用一型一密认证方式获取到设备密钥后,请将设备密钥持久固化至设备。若设备需连接至物联网平台,请参考上述一机一密流程。
免预注册和预注册区别如下:
区别 | 预注册 | 免预注册 |
区别 | 预注册 | 免预注册 |
通信协议 | MQTT、HTTPS | MQTT |
地域支持 |
| 华东2(上海)、华北2(北京) |
返回的设备密钥 | DeviceSecret具体使用方式,请参考上述一机一密示例中的Step1。 | 设备的ClientID和DeviceToken,请将其持久固化至设备,以便连云等其他功能使用。具体使用方式,请参考上述一机一密示例中的Step3。 |
添加设备 | 需要在物联网平台预注册设备DeviceName。 | 不需要在物联网平台预注册设备DeviceName。 |
使用次数限制 |
| 物联网平台允许最多5个物理设备使用同一组ProductKey、ProductSecret、DeviceName进行激活,并为不同物理设备颁发不同的ClientID、DeviceToken。 |
示例代码如下:
String deviceName = "${YourDeviceName}";
String productKey = "${YourProductKey}";
String productSecret = "${YourProductSecret}";
//动态注册step1: 确定一型一密的类型(免预注册, 还是非免预注册)
//case 1: 如果registerType里面填写了regnwl, 表明设备的一型一密方式为免预注册(即无需创建设备)
//case 2: 如果这个字段为空, 或填写"register", 则表示为需要预注册的一型一密(需要实现创建设备)
String registerType = "register";
//动态注册step2: 设置动态注册的注册接入点域名
MqttConfigure.mqttHost = "ssl://${YourMqttHostUrl}:8883";
MqttInitParams initParams = new MqttInitParams(productKey, productSecret, deviceName, "",registerType);
//动态注册step3: 如果用户所用的实例为新版本的公共实例或者企业实例(控制台中有实例详情的页面), 需设置动态注册的实例id
initParams.instanceId = "${YourInstanceId}";
final Object lock = new Object();
LinkKit.getInstance().deviceDynamicRegister(initParams, new IOnCallListener() {
@Override
public void onSuccess(com.aliyun.alink.linksdk.channel.core.base.ARequest request, com.aliyun.alink.linksdk.channel.core.base.AResponse response) {
try {
String responseData = new String((byte[]) response.data);
JSONObject jsonObject = JSONObject.parseObject(responseData);
// 一型一密预注册返回
String deviceSecret = jsonObject.getString("deviceSecret");
// 一型一密免预注册返回
String clientId = jsonObject.getString("clientId");
String deviceToken = jsonObject.getString("deviceToken");
//TODO: 请用户保存用户密钥,不要在此做连云的操作,要等step 4执行完成后再做连云的操作(例如在其onSuccess分支中进行连云)
//让等待的api继续执行
synchronized (lock){
lock.notify();
}
} catch (Exception e) {
}
}
@Override
public void onFailed(ARequest aRequest, com.aliyun.alink.linksdk.channel.core.base.AError aError) {
System.out.println("mqtt dynamic registration failed");
//让等待的api继续执行
synchronized (lock){
lock.notify();
}
}
@Override
public boolean needUISafety() {
return false;
}
});
try {
//等待下行报文,一般1s内就有回复
synchronized (lock){
lock.wait(3000);
}
//动态注册step4: 关闭动态注册的实例。
//不要在LinkKit.getInstance().deviceDynamicRegister回调中执行下述函数,否则会报错
LinkKit.getInstance().stopDeviceDynamicRegister(2000, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken iMqttToken) {
System.out.println("mqtt dynamic registration success");
//TODO: 在此处参考一机一密进行连云和初始化
}
@Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
System.out.println("mqtt dynamic registration failed");
}
});
} catch (Exception e) {
}
设置接入域名
示例代码如下:
// 设置MQTT请求域名LinkKitInitParams初始化参数
IoTMqttClientConfig clientConfig = new IoTMqttClientConfig();
clientConfig.channelHost = "a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com:8883";
linkKitInitParams.mqttClientConfig = clientConfig;
参数说明:
参数 | 示例 | 说明 |
参数 | 示例 | 说明 |
channelHost | a18wP******.iot-as-mqtt.cn-shanghai.aliyuncs.com:8883 | 设备的
新旧版公共实例和企业版实例、以及接入域名的更多信息,请参见查看实例终端节点。 |
更多设置
您可以设置以下参数,实现设备接入相关的更多设置。
MQTT连接:
配置项
说明
相关代码
配置项
说明
相关代码
保活时间
设置设备的保活时间。通过该设置实现设备与物联网平台保持长连接。
MqttConfigure.setKeepAliveInterval(int interval);
QoS等级
设置QoS(Quality of Service)等级,即物联网平台与设备之间保证交付信息的协议。仅支持:
0
:最多一次。1
:最少一次。
- qos设置 MqttPublishRequest request = new MqttPublishRequest(); // 支持 0 和 1, 默认0 request.qos = 0; request.isRPC = false; request.topic = topic.replace("request", "response"); String resId = topic.substring(topic.indexOf("rrpc/request/")+13); request.msgId = resId; // TODO 用户根据实际情况填写,仅做参考 request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";
离线消息
通过cleanSession,设置是否接收离线消息。
/** * 设置MQTT初始化参数 */ IoTMqttClientConfig config = new IoTMqttClientConfig(); config.productKey = deviceInfoData.productKey; config.deviceName = deviceInfoData.deviceName; config.deviceSecret = deviceInfoData.deviceSecret; config.channelHost = pk + ".iot-as-mqtt." + deviceInfoData.region + ".aliyuncs.com:1883"; /** * 是否接受离线消息 * 对应 receiveOfflineMsg = !cleanSession, 默认不接受离线消息 */ config.receiveOfflineMsg = false; params.mqttClientConfig = config;
日志与Log4j支持:
用户可以通过如下日志输出Debug日志:
ALog.setLevel(ALog.LEVEL_DEBUG); MqttLogger.isLoggable = true; // 输出底层MQTT库的全量日志, 默认关闭
Java Link SDK从1.2.3.1版本起,提供了一个全量的拦截器,支持用户重写拦截器的
log
函数,实现自定义的日志处理。例如将日志通过Log4j工具持久化到文件中。日志输出示例代码:
ALog.setLogDispatcher(new ILogDispatcher() { @Override public void log(int level, String prefix, String msg) { switch (level){ case LEVEL_DEBUG: System.out.println("debug:"+ prefix + msg); break; case LEVEL_INFO: System.out.println("info:" + prefix + msg); break; case LEVEL_ERROR: System.out.println("error:" + prefix + msg); break; case LEVEL_WARNING: System.out.println("warnings:" + prefix + msg); break; default: System.out.println("other:" + prefix + msg); } } });
连接状态与下行消息监听:
如果需要监听设备的上下线信息,以及物联网平台下发的消息,可以设置以下监听器。
IConnectNotifyListener notifyListener = new IConnectNotifyListener() { @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // 物联网平台下行数据回调,包括connectId、连接类型、下行Topic和aMessage下行数据 //String pushData = new String((byte[]) aMessage.data); // pushData示例 {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"} // 上一行代码表示method服务类型以及params下推数据内容 } @Override public boolean shouldHandle(String connectId, String topic) { // 选择是否不处理某个Topic的下行数据 // 如果不处理某个Topic,则onNotify不会收到对应Topic的下行数据 return true; //TODO 根据实际情况,编写要处理的监听逻辑。 } @Override public void onConnectStateChange(String connectId, ConnectState connectState) { // 对应连接类型的连接状态变化回调,具体连接状态参考SDK ConnectState //当SDK因网络波动断开连接时,会自动尝试重连,重试的间隔是1s、2s、4s、8s...128s...128s, 到了最大间隔128s后,会一直以128s为间隔重连直到连云成功。 } } // 注册下行监听,包括长连接的状态和下行的数据 LinkKit.getInstance().registerOnNotifyListener(notifyListener);
反初始化:
如果需要注销初始化,请参考如下示例代码。
// 取消注册 notifyListener,notifyListener对象需和注册的时候是同一个对象 LinkKit.getInstance().unRegisterOnNotifyListener(notifyListener); LinkKit.getInstance().deinit();
- 本页导读 (1)
- 前提条件
- 背景信息
- 一机一密
- 动态注册
- 设置接入域名
- 更多设置