基于MQTT Topic通信

Android SDK提供与阿里云物联网平台通信的基础能力接口,本文介绍通过自定义Topic实现发布、订阅、取消订阅的基础能力。

具体代码实现请参见Demo中的MqttActivity.java。

发布消息

更多发布消息内容,请参见MqttPublishRequest

  • 不返回应答

    适用于设备上行消息,物联网平台不回复,或者物联网平台进行了回复但设备端不需要做处理的场景。

    // 发布
    MqttPublishRequest request = new MqttPublishRequest();
    // 设置是否需要应答。
    request.isRPC = false;
    // 设置topic,设备通过该Topic向物联网平台发送消息。以下Topic为示例,需替换为用户自己设备的Topic。
    request.topic = "/a18wP******/LightSwitch/user/update";
    // 设置qos
    request.qos = 0;
    String data = "hello world"; //TODO:data 设置需要发布的数据
    request.payloadObj = data;
    LinkKit.getInstance().publish(request, new IConnectSendListener() {
        @Override
        public void onResponse(ARequest aRequest, AResponse aResponse) {
            // 消息成功提交给操作系统的发送缓冲区。
            // 在网络波动等异常情况下,消息可能无法到达云端。
            // 如果上行的消息有对应的下行的reply, 建议通过reply报文来确认上行消息的到达。
        }
        @Override
        public void onFailure(ARequest aRequest, AError aError) {
            // 发布失败
        }
    });                       

    参数

    示例

    说明

    isRPC

    false

    是否为RPC请求,如果是,则需要等待 replyTopic消息后才Rsp。

    默认为false,表示不需应答。

    topic

    /a18wP******/LightSwitch/user/update

    拥有发布权限的Topic。设备通过该Topic向物联网平台发送消息。

    qos

    0

    设置MQTT请求中QOS的值,默认为0。

    payloadObj

    {"id":"160865432","method":"thing.event.property.post","params":{"LightSwitch":1},"version":"1.0"}

    需要发布的数据,可以为任意格式数据。如果格式为JSON String,其中id字段需要保持每次唯一,不可重复,请使用自增的方式进行设置ID字段。示例中id字段为160865432,则下次id字段应为160865433。

  • 返回应答

    • 适用于用户将设备上行的消息流转到自己的业务服务器,业务服务器再发送下行消息给设备的场景。

    • 适用于用户使用Alink协议的Topic,并且协议规定服务端会回复reply报文的场景。

    // 发布
    MqttPublishRequest request = new MqttPublishRequest();
    // 设置是否需要应答。设置为true,表示期望收到物联网平台的下行回复。
    request.isRPC = true;
    // 设置qos
    request.qos = 0;
    // 设置topic,设备通过该Topic向物联网平台发送消息。以下Topic为示例,需替换为用户自己设备的Topic。
    request.topic = "/a18wP******/LightSwitch/user/update";
    //设置物联网平台答复的topic,若不设置,则默认为 topic+“_reply”。
    request.replyTopic = "/a18wP******/LightSwitch/user/update_reply";
    String data = "hello world"; //TODO:data 设置需要发
    request.payloadObj = data;
    //demo的BaseTemplateActivity提供了参考的消息响应的类, 下行消息会在其中的onResponse中给到用户
    LinkKit.getInstance().publish(request, new IConnectSendListener() {
        @Override
        public void onResponse(ARequest aRequest, AResponse aResponse) {
            // 发布成功
        }
        @Override
        public void onFailure(ARequest aRequest, AError aError) {
            // 发布失败
        }  
    });                    

    参数

    示例

    说明

    isRPC

    true

    是否为RPC请求,如果是,则需要等待 replyTopic消息后才Rsp。

    设置为true,表示期望收到物联网平台的下行回复。

    qos

    0

    设置MQTT请求中QoS的值,默认为0。

    topic

    /a18wP******/LightSwitch/user/update

    拥有发布权限的Topic。设备通过该Topic向物联网平台发送消息。

    replyTopic

    /a18wP******/LightSwitch/user/update_reply

    设置物联网平台答复的topic,若不设置,则默认为 topic+“_reply”。

    payloadObj

    {"id":"160865432","method":"thing.event.property.post","params":{"LightSwitch":1},"version":"1.0"}

    需要发布的数据,格式必须为JSON String,其中id字段需要保持每次唯一,不可重复,请使用自增的方式进行设置ID字段。示例中id字段为160865432,则下次id字段应为160865433。

说明

设备发送消息的回调onResponse/onFailure,默认是在UI线程透出。自lp-iot-linkkit的1.7.3版本起,您可以通过PersistentConnect.mNotifySendResultOnMainThread = false;选择将消息通过非UI线程透出。对于UI线程业务繁忙的场景,建议将该配置项设置为false

订阅消息

您可以订阅指定Topic的消息,订阅关系将保存在物联网平台。物联网平台收到指定Topic发布的消息后,会将消息转发给设备。更多内容,请参见MqttSubscribeRequest

订阅成功后,相应的下行消息,会通过认证与连接连接状态与下行消息监听中的IConnectNotifyListener对象中透出。

示例代码:

// 订阅
MqttSubscribeRequest subscribeRequest = new MqttSubscribeRequest();
// subTopic 替换成您需要订阅的 topic
subscribeRequest.topic = subTopic;
subscribeRequest.isSubscribe = true;
subscribeRequest.qos = 0; // 支持0或者1
LinkKit.getInstance().subscribe(subscribeRequest, new IConnectSubscribeListener() {
    @Override
    public void onSuccess() {
        // 订阅成功
    }
    @Override
    public void onFailure(AError aError) {
        // 订阅失败
    }
});                      

如果设备不再需要订阅指定Topic,需要主动取消订阅。否则订阅关系一直存在,您将持续收到订阅Topic发送的消息。具体内容,请参见下文取消订阅

取消订阅

// 取消订阅
MqttSubscribeRequest unsubRequest = new MqttSubscribeRequest();
// unSubTopic 替换成您需要取消订阅的topic
unsubRequest.topic = unSubTopic;
unsubRequest.isSubscribe = false;
LinkKit.getInstance().unsubscribe(unsubRequest, new IConnectUnscribeListener() {
    @Override
    public void onSuccess() {
        // 取消订阅成功
    }
    @Override
    public void onFailure(AError aError) {
        // 取消订阅失败
    }
});