All Products
Search
Document Center

IoT Platform:RRPC

Last Updated:Oct 22, 2023

Background information

IoT Platform provides the revert-RPC (RRPC) feature to allow you to initiate an RRPC request to a device by calling an API operation. The response from the device is synchronously returned.

The device receives a synchronous request topic in the format of /ext/rrpc/{messageId}/{rrpc_topic} or a synchronous request in the format of /sys/{pk}/{dn}/rrpc/request/${msgId}. After the device receives the message, the device processes the message and publishes the result to /ext/rrpc/{messageId}/{rrpc_topic} or /ext/rrpc/${msgId}/${topic}.

API operation for messaging - RRpc

You can call the RRpc operation of IoT Platform to trigger IoT Platform to send a synchronous RRPC request to a device.

API operation for device management - InvokeThingsService

You can call the InvokeThingsService operation of IoT Platform to initiate a synchronous RRPC request to a device. Alternatively, you can define a service of the device as a synchronous service in the IoT Platform console and call the synchronous service.

Prerequisites

The SDK is initialized on the device, which means that a Message Queuing Telemetry Transport (MQTT) connection is created.

RRPC listening and response

The device can use a listener to listen to downstream RRPC requests from IoT Platform. The request initiator can specify the topic that is used to send the request.

// Set a global listener that listens to downstream data.
LinkKit.getInstance().registerOnPushListener(notifyListener);
        /**
     * The downstream data listener. All callbacks for MQTT data from IoT Platform are implemented by using this listener.
     */
private static IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
    /**
         * The onNotify callback is triggered unless shouldHandle explicitly specify that the topic is not processed.
         * @param connectId indicates the connection type. This parameter is used to check whether the connection is a persistent connection. connectId == ConnectSDK.getInstance().getPersistentConnectId()
         * @param topic indicates the downstream topic, which stores downstream data from IoT Platform.
         * @param aMessage indicates the content of downstream data.
         */
    @Override
    public void onNotify(String connectId, String topic, AMessage aMessage) {
        String data = new String((byte[]) aMessage.data);
        // An example of data returned from IoT Platform: data = {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"}
    }
    /**
         * @param connectId indicates the connection type. This parameter is used to check whether the connection is a persistent connection. connectId == ConnectSDK.getInstance().getPersistentConnectId()
         * @param topic indicates the downstream topic, which stores downstream data from IoT Platform.
         * @ return specifies whether to process this topic. If this parameter is set to true, the onNotify callback is triggered. If this parameter is set to false, the onNotify callback is not triggered. We recommend that you use the default value true. 
         */
    @Override
    public boolean shouldHandle(String connectId, String topic) {
        return true;
    }
    /**
         * @param connectId indicates the connection type. This parameter is used to check whether the connection is a persistent connection. connectId == ConnectSDK.getInstance().getPersistentConnectId()
         * @param connectState {@link ConnectState}
         *     CONNECTED indicates that the connection is successful.
         *     DISCONNECTED indicates that the connection is closed.
         *     CONNECTING indicates that the connection is being established.
         *     CONNECTFAIL indicates that the connection failed.
         */
    @Override
    public void onConnectStateChange(String connectId, ConnectState connectState) {
        Log.d(TAG, "onConnectStateChange() called with: connectId = [" + connectId + "], connectState = [" + connectState + "]");
    }
};

Sample code

Device

An RRPC response contains the data that the request initiator wants. In the following sample code, an empty data object is returned.

// You can use the global listener to listen to data from IoT Platform.
LinkKit.getInstance().registerOnPushListener(notifyListener);
private IConnectNotifyListener notifyListener = new IConnectNotifyListener() {
    @Override
    public void onNotify(String connectId, String topic, AMessage aMessage) {
            if (CONNECT_ID.equals(connectId) && !TextUtils.isEmpty(topic) &&
                    topic.startsWith("/ext/rrpc/")) {
            // Example: topic=/ext/rrpc/1138654706478941696//a1ExY4afKY1/testDevice/user/get
            //ALog.d(TAG, "receice Message=" + new String((byte[]) aMessage.data));
            // Sample data returned from IoT Platform: {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"}
            MqttPublishRequest request = new MqttPublishRequest();
            request.isRPC = false;
            request.topic = topic;
            String[] array = topic.split("/");
            String resId = array[3];
            request.msgId = resId;
            // TODO: Design your own logic. The code here is for reference only.
            request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";
            LinkKit.getInstance().publish(request, new IConnectSendListener() {
                @Override
                public void onResponse(ARequest aRequest, AResponse aResponse) {
                                        // The response is successful.
                }
                @Override
                public void onFailure(ARequest aRequest, AError aError) {
                                        // No successful response is returned.
                }
                    });
        }
    }
    @Override
    public boolean shouldHandle(String connectId, String topic) {
        return true;
    }
    @Override
    public void onConnectStateChange(String connectId, ConnectState connectState) {
        Log.d(TAG, "onConnectStateChange() called with: connectId = [" + connectId + "], connectState = [" + connectState + "]");
    }
};