全部产品
云市场

认证与连接

更新时间:2019-02-21 20:49:36

本文介绍如何进行 SDK 初始化,建立设备与云端的连接。

设备认证

设备的身份认证支持三种方法,不同方法需填写不同信息。

  • 使用三元组认证方式,需要用户为每个设备提供ProductKey、DeviceName和DeviceSecret。
  • 使用动态注册认证方式,需要有ProductKey、ProductSecret和DeviceName,并在控制台开启动态注册。
  • 使用ID2认证方式

三元组认证方式

三元组认证方式指设备在出厂前已经为每个设备烧写了ProductKey、DeviceName、DeviceSecret,注意每个设备的三元组不能一样,否则会出现一个设备上线导致另外一个设备下线的情况。

初始化代码如下所示:

  1. /**
  2. * 设置设备三元组信息
  3. */
  4. DeviceInfo deviceInfo = new DeviceInfo();
  5. deviceInfo.productKey = productKey;// 产品类型
  6. deviceInfo.deviceName = deviceName;// 设备名称
  7. deviceInfo.deviceSecret = deviceSecret;// 设备密钥
  8. /**
  9. * 设置设备当前的初始状态值,属性需要和云端创建的物模型属性一致
  10. * 如果这里什么属性都不填,物模型就没有当前设备相关属性的初始值。
  11. * 用户调用物模型上报接口之后,物模型会有相关数据缓存。
  12. */
  13. Map<String, ValueWrapper> propertyValues = new HashMap<>();
  14. // 示例
  15. // propertyValues.put("LightSwitch", new ValueWrapper.BooleanValueWrapper(0));
  16. IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret);
  17. LinkKitInitParams params = new LinkKitInitParams();
  18. params.deviceInfo = deviceInfo;
  19. params.propertyValues = propertyValues;
  20. params.mqttClientConfig = clientConfig;
  21. /**
  22. * 设备初始化建联
  23. * onError 初始化建联失败,需要用户重试初始化。如因网络问题导致初始化失败。
  24. * onInitDone 初始化成功
  25. */
  26. LinkKit.getInstance().init(context, params, new ILinkKitConnectListener() {
  27. @Override
  28. public void onError(AError error) {
  29. // 初始化失败 error包含初始化错误信息
  30. }
  31. @Override
  32. public void onInitDone(Object data) {
  33. // 初始化成功 data 作为预留参数
  34. }
  35. });

动态注册

动态注册指设备出厂前烧写了ProductKey、ProductSecret以及DeviceName,其中DeviceName是厂商指定的,通常为设备的MAC地址或者SN,由于设备即使不连接阿里云也需要烧写MAC地址或者SN,所以使用动态注册方案对设备厂商的产线无需做更改,因为ProductKey、ProductSecret可以在软件固件中进行指定。

动态注册将会从云端获取设备的DeviceSecret,然后仍然使用三元组认证方式与云端交互来进行设备认证。所以设备需要将收到的DeviceSecret持久化存储,确保设备进行OTA升级、配置清除之后仍然存在

动态初始化成功之后不能再执行动态初始化,后续应用重新启动(包括卸载后重装启动)都需要从持久化存储中获取三元组,然后执行初始化建联(即三元组认证方式与云端建立连接)。

  1. // ####### 一型一密动态注册接口开始 ######
  2. /**
  3. * 注意:动态注册成功,设备上线之后,不能再次执行动态注册,云端会返回已注册错误信息。
  4. * 因此用户在编程时首先需要判断设备是否已获取过deviceSecret,没有获取过的情况下再
  5. * 调用动态注册接口去获取deviceSecret
  6. */
  7. DeviceInfo myDeviceInfo = new DeviceInfo();
  8. myDeviceInfo.productKey = productKey;
  9. myDeviceInfo.deviceName = deviceName;
  10. myDeviceInfo.productSecret = productSecret;
  11. LinkKitInitParams params = new LinkKitInitParams();
  12. params.deviceInfo = myDeviceInfo;
  13. // 设置动态注册请求 path 和 域名,域名使用默认即可
  14. HubApiRequest hubApiRequest = new HubApiRequest();
  15. hubApiRequest.path = "/auth/register/device";
  16. LinkKit.getInstance().deviceRegister(context, params, hubApiRequest, new IConnectSendListener() {
  17. @Override
  18. public void onResponse(ARequest aRequest, AResponse aResponse) {
  19. // aRequest 用户的请求数据
  20. if (aResponse != null && aResponse.data != null) {
  21. ResponseModel<Map<String, String>> response = JSONObject.parseObject(aResponse.data.toString(),
  22. new TypeReference<ResponseModel<Map<String, String>>>() {
  23. }.getType());
  24. if ("200".equals(response.code) && response.data != null && response.data.containsKey("deviceSecret") &&
  25. !TextUtils.isEmpty(response.data.get("deviceSecret"))) {
  26. deviceInfo.deviceSecret = response.data.get("deviceSecret");
  27. // getDeviceSecret success, to build connection.
  28. // 持久化 deviceSecret 初始化建联的时候需要
  29. // TODO 用户需要按照实际场景持久化设备的三元组信息,用于后续的连接
  30. // 成功获取 deviceSecret,调用初始化接口建联
  31. // TODO 调用设备初始化建联
  32. }
  33. }
  34. }
  35. @Override
  36. public void onFailure(ARequest aRequest, AError aError) {
  37. Log.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
  38. }
  39. });
  40. // ####### 一型一密动态注册接口结束 ######

ID2设备认证

SDK初始化的时候添加以下设置:

  1. /**
  2. * 云端创建使用 iTLS 认证方式的设备采用这种方式初始化
  3. * 产品需要到 ID2 授权
  4. */
  5. IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret);
  6. clientConfig.channelHost = productKey + ".itls.cn-shanghai.aliyuncs.com:1883";
  7. clientConfig.productSecret = productSecret;
  8. clientConfig.secureMode = 8;
  9. linkKitInitParams.mqttClientConfig = clientConfig;

SDK 反初始化

如果需要注销初始化,调用如下接口。

  1. // 取消注册 notifyListener,notifyListener对象需和注册的时候是同一个对象
  2. LinkKit.getInstance().unRegisterOnPushListener(notifyListener);
  3. LinkKit.getInstance().deinit();

其他设置

日志开关

打开SDK内部日志输出开关:

  1. ALog.setLevel(ALog.LEVEL_DEBUG);

连接状态监听

如果需要监听设备的上下线信息,云端下发的所有数据,可以设置以下监听器。

  1. IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
  2. @Override
  3. public void onNotify(String connectId, String topic, AMessage aMessage) {
  4. // 云端下行数据回调
  5. // connectId 连接类型 topic 下行 topic; aMessage 下行数据
  6. //String pushData = new String((byte[]) aMessage.data);
  7. // pushData 示例 {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"}
  8. // method 服务类型; params 下推数据内容
  9. }
  10. @Override
  11. public boolean shouldHandle(String connectId, String topic) {
  12. // 选择是否不处理某个 topic 的下行数据
  13. // 如果不处理某个topic,则onNotify不会收到对应topic的下行数据
  14. return true; //TODO 根基实际情况设置
  15. }
  16. @Override
  17. public void onConnectStateChange(String connectId, ConnectState connectState) {
  18. // 对应连接类型的连接状态变化回调,具体连接状态参考 SDK ConnectState
  19. }
  20. }
  21. // 注册下行监听,包括长连接的状态和云端下行的数据
  22. LinkKit.getInstance().registerOnPushListener(notifyListener);

请求域名

云端接口的请求域名,请参考地域和可用区查看支持的域名。

  • MQTT域名设置SDK初始化的时候添加以下设置。

    1. // 设置 Mqtt 请求域名 LinkKitInitParams 初始化参数
    2. IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret);
    3. // 慎用 设置 mqtt 请求域名,默认 productKey+".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883" ,如果无具体的业务需求,请不要设置。
    4. //clientConfig.channelHost = "xxx";
    5. linkKitInitParams.mqttClientConfig = clientConfig;
  • 一型一密域名设置SDK动态注册的时候添加以下设置。

    1. HubApiRequest hubApiRequest = new HubApiRequest();
    2. // 一型一密域名 默认"iot-auth.cn-shanghai.aliyuncs.com"
    3. // hubApiRequest.domain = "xxx"; // 如无特殊需求,不要设置
    4. hubApiRequest.path = "/auth/register/device";

Mqtt 连接参数

  • 设置Mqtt Keep-Alive 时间
    1. // interval 单位秒
    2. MqttConfigure.setKeepAliveInterval(int interval);
  • qos设置
    1. MqttPublishRequest request = new MqttPublishRequest();
    2. // 支持 0 和 1, 默认0
    3. request.qos = 0;
    4. request.isRPC = false;
    5. request.topic = topic.replace("request", "response");
    6. String resId = topic.substring(topic.indexOf("rrpc/request/")+13);
    7. request.msgId = resId;
    8. // TODO 用户根据实际情况填写 仅做参考
    9. request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";
  • cleanSession 设置
    1. IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret);
    2. // 对应 receiveOfflineMsg = !cleanSession, 默认不接受离线消息
    3. clientConfig.receiveOfflineMsg = true;