# 使用设备SDK进行消息收发
#### 概述
设备可以通过SDK快速连接华为云IoTDA并进行消息上下行通信，本文基于Java示例代码演示设备通过MQTTS/MQTT协议接入华为云IoTDA服务并通过Topic发布和订阅消息。
图1SDK与IoTDA的消息交互流程   
![](https://support.huaweicloud.com/qs-iothub/figure/zh-cn_image_0000001989625474.png)
#### 前提条件
- 已注册华为云官方账号。未注册可单击[注册页面](https://reg.huaweicloud.com/registerui/public/custom/register.html#/register)完成注册。

- 已完成[实名认证](https://account.huaweicloud.com/usercenter/#/accountindex/realNameAuth)。
- 已开通设备接入服务。操作可参考[开通服务](https://support.huaweicloud.com/qs-iothub/iot_05_0008.html)。
- 已创建产品和设备。操作可参考[注册设备](https://support.huaweicloud.com/qs-iothub/iot_05_0009.html)。
 
#### 设备侧SDK发送消息
1. 配置设备侧SDK的Maven依赖。
   ```
   <dependency>
   <groupId>com.huaweicloud</groupId>
   <artifactId>iot-device-sdk-java</artifactId>
   <version>[1.2.1,)</version>
   </dependency>
   ```
   
2. 建立设备与华为云IoTDA的连接。
   1. 参考[样例代码](https://github.com/huaweicloud/huaweicloud-iot-device-sdk-java/blob/master/iot-device-demo/src/main/java/com/huaweicloud/sdk/iot/device/demo/device/MessageSample.java)，在建立连接之前，修改设备连接参数。
      ```
      //域名获取方式：登录华为云IoTDA控制台左侧导航栏“总览”页签，在选择的实例基本信息中，单击“接入信息”。选择“设备接入”8883端口对应的接入地址。
      IoTDevice device = new IoTDevice("ssl://<接入地址>:8883", "your device id",
      "your device secret", tmpCAFile);
      device.getClient().setConnectListener(new MessageSample(device));
      if (device.init() != 0) {
      return;
      }
      ```
      
   
   2. 设备接入平台后，参考如下代码订阅平台下发的消息。
      ```
      @Override
          public void connectComplete(boolean reconnect, String serverURI) {
              // 订阅下行消息
              device.getClient().subscribeTopic("/test/cloudToDevice", new ActionListener() {
                  @Override
                  public void onSuccess(Object context) {
                      System.out.println("subscribeTopic success");
                  }
                  @Override
                  public void onFailure(Object context, Throwable var2) {
                      System.out.println("subscribeTopic failure");
                  }
              } , rawMessage -> {
                  System.out.println(" on receive message topic : " + rawMessage.getTopic() + " , payload : " + new String(
                      rawMessage.getPayload(), StandardCharsets.UTF_8));
              }, 1);
          }
      ```
      
   
   3. 完成上述信息的修改后，运行程序，在平台可以看到设备显示在线。
      图2设备列表-设备在线   
      ![](https://support.huaweicloud.com/qs-iothub/figure/zh-cn_image_0000001950367902.png "点击放大") 
    
3. 上报设备消息，参考样例代码，在建立连接后，指定Topic上报消息。
   ```
   device.getClient().publishRawMessage(new RawMessage("/test/deviceToCloud", "hello", 1), new ActionListener() {
       @Override
       public void onSuccess(Object context) {
           System.out.println("reportDeviceMessage success: ");
       }
       @Override
       public void onFailure(Object context, Throwable var2) {
           System.out.println("reportDeviceMessage fail: " + var2);
       }
   });
   ```
   
4. 访问[设备接入服务](https://www.huaweicloud.com/product/iothub.html)，单击"管理控制台"进入设备接入控制台。选择您的实例，单击实例卡片进入。
5. 在左侧导航栏选择"设备\>所有设备"，单击"详情"，在设备详情的消息跟踪页面可以查看平台是否收到对应消息。
   图3消息跟踪-查看消息跟踪   
   ![](https://support.huaweicloud.com/qs-iothub/figure/zh-cn_image_0000001981577917.png "点击放大") 
 
#### 应用侧SDK接收消息
设备通过SDK将消息发送到平台后，可以配置[数据转发](https://support.huaweicloud.com/usermanual-iothub/iot_01_0024.html)将设备上报的消息平滑流转至消息中间件、存储、数据分析或业务应用。本文以[Java SDK接入示例](https://support.huaweicloud.com/usermanual-iothub/iot_01_00100_3.html)接收设备上报的消息并进行业务处理。
#### 应用侧SDK下发消息
配置应用侧SDK下发消息。
1. 配置Maven依赖，本示例使用的开发环境为JDK 1.8及以上版本。SDK代码获取：[SDK下载](https://support.huaweicloud.com/sdkreference-iothub/iot_10_1002.html)。
   ```
   <dependency>
       <groupId>com.huaweicloud.sdk</groupId>
       <artifactId>huaweicloud-sdk-core</artifactId>
       <version>[3.0.40-rc, 3.2.0)</version>
   </dependency>
   <dependency>
       <groupId>com.huaweicloud.sdk</groupId>
       <artifactId>huaweicloud-sdk-iotda</artifactId>
       <version>[3.0.40-rc, 3.2.0)</version>
   </dependency>
   ```
   
2. 应用侧向指定设备下发消息样例如下：
   ```
   public class MessageDistributionSolution {
       // REGION_ID：如果是上海一，请填写"cn-east-3"；如果是北京四，请填写"cn-north-4";如果是华南广州，请填写"cn-south-4"
       private static final String REGION_ID = "<YOUR REGION ID>";
       // ENDPOINT：请在控制台的"总览"界面的"平台接入地址"中查看“应用侧”的https接入地址。
       private static final String ENDPOINT = "<YOUR ENDPOINT>";
       // 标准版/企业版：需自行创建Region对象
       public static final Region REGION_CN_NORTH_4 = new Region(REGION_ID, ENDPOINT);
       public static void main(String[] args) {
           String ak = "<YOUR AK>";
           String sk = "<YOUR SK>";
           String projectId = "<YOUR PROJECTID>";
           // 创建认证
           ICredential auth = new BasicCredentials().withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE)
               .withAk(ak)
               .withSk(sk)
               .withProjectId(projectId);
           // 创建IoTDAClient实例并初始化
           IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth)
               // 基础版：请选择IoTDARegion中的Region对象
               //.withRegion(IoTDARegion.CN_NORTH_4)
               // 标准版/企业版：需自行创建Region对象
               .withRegion(REGION_CN_NORTH_4).build();
           // 实例化请求对象
           CreateMessageRequest request = new CreateMessageRequest();
           request.withDeviceId("<YOUR DEVICE_ID>");
           DeviceMessageRequest body = new DeviceMessageRequest();
           body.withPayloadFormat("raw");
           body.withTopicFullName("/test/cloudToDevice");
           body.withMessage("hello");
           request.withBody(body);
           try {
               CreateMessageResponse response = client.createMessage(request);
               System.out.println(response.toString());
           } catch (ConnectionException e) {
               e.printStackTrace();
           } catch (RequestTimeoutException e) {
               e.printStackTrace();
           } catch (ServiceResponseException e) {
               e.printStackTrace();
               System.out.println(e.getHttpStatusCode());
               System.out.println(e.getRequestId());
               System.out.println(e.getErrorCode());
               System.out.println(e.getErrorMsg());
           }
       }
   }
   ```
   
3. 查看设备端日志，可以看到应用给设备下发的消息如下：
   ```
   on receive message topic : /test/cloudToDevice , payload : hello
   ```
   
 
