了解和调用 IoT 中心的直接方法Understand and invoke direct methods from IoT Hub

借助 IoT 中心,用户可以从云中对设备调用直接方法。IoT Hub gives you the ability to invoke direct methods on devices from the cloud. 直接方法表示与设备进行的请求-答复式交互,类似于会立即成功或失败(在用户指定的超时时间后)的 HTTP 调用。Direct methods represent a request-reply interaction with a device similar to an HTTP call in that they succeed or fail immediately (after a user-specified timeout). 此方法用于即时操作过程不同的情况,即时操作的不同取决于设备能否响应。This approach is useful for scenarios where the course of immediate action is different depending on whether the device was able to respond.

Note

本文中所述的功能仅可在 IoT 中心的标准层中使用。The features described in this article are only available in the standard tier of IoT hub. 有关基本和标准 IoT 中心层的详细信息,请参阅如何选择合适的 IoT 中心层For more information about the basic and standard IoT Hub tiers, see How to choose the right IoT Hub tier.

每个设备方法针对一个设备。Each device method targets a single device. 在多个设备上计划作业展示了一种方法,用于对多个设备调用直接方法,并为已断开连接的设备计划方法调用。Schedule jobs on multiple devices shows how to provide a way to invoke direct methods on multiple devices, and schedule method invocation for disconnected devices.

只要拥有 IoT 中心的“服务连接”权限,任何人都可以调用设备上的方法。Anyone with service connect permissions on IoT Hub may invoke a method on a device.

直接方法遵循请求-响应模式,适用于需要立即确认其结果的通信。Direct methods follow a request-response pattern and are meant for communications that require immediate confirmation of their result. 例如对设备的交互式控制,如打开风扇。For example, interactive control of the device, such as turning on a fan.

如果在使用所需属性、直接方法或云到设备消息方面有任何疑问,请参阅 云到设备通信指南Refer to Cloud-to-device communication guidance if in doubt between using desired properties, direct methods, or cloud-to-device messages.

方法生命周期Method lifecycle

直接方法在设备上实现,可能需要在方法有效负载中进行 0 次或 0 次以上的输入才能正确地实例化。Direct methods are implemented on the device and may require zero or more inputs in the method payload to correctly instantiate. 可以通过面向服务的 URI ({iot hub}/twins/{device id}/methods/) 调用直接方法。You invoke a direct method through a service-facing URI ({iot hub}/twins/{device id}/methods/). 设备通过特定于设备的 MQTT 主题 ($iothub/methods/POST/{method name}/) 或通过 AMQP 链接(IoThub-methodnameIoThub-status 应用程序属性)接收直接方法。A device receives direct methods through a device-specific MQTT topic ($iothub/methods/POST/{method name}/) or through AMQP links (the IoThub-methodname and IoThub-status application properties).

Note

调用设备上的直接方法时,属性名称和值只能包含 US ASCII 可打印字母数字,但下列组中的任一项除外:{'$', '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[', ']', '?', '=', '{', '}', SP, HT}When you invoke a direct method on a device, property names and values can only contain US-ASCII printable alphanumeric, except any in the following set: {'$', '(', ')', '<', '>', '@', ',', ';', ':', '\', '"', '/', '[', ']', '?', '=', '{', '}', SP, HT}.

直接方法是同步的,在超时期限(默认:30 秒,最长可设置为 300 秒)过后,其结果不是成功就是失败。Direct methods are synchronous and either succeed or fail after the timeout period (default: 30 seconds, settable up to 300 seconds). 直接方法适用于交互式场景,即当且仅当设备处于联机状态且可接收命令时,用户希望设备做出响应。Direct methods are useful in interactive scenarios where you want a device to act if and only if the device is online and receiving commands. 例如,打开手机的灯。For example, turning on a light from a phone. 在此类方案中,用户需要立即看到结果是成功还是失败,以便云服务可以尽快根据结果进行操作。In these scenarios, you want to see an immediate success or failure so the cloud service can act on the result as soon as possible. 设备可能返回某些消息正文作为方法的结果,但系统不会要求方法一定这样做。The device may return some message body as a result of the method, but it isn't required for the method to do so. 无法保证基于方法调用的排序或者任何并发语义。There is no guarantee on ordering or any concurrency semantics on method calls.

直接方法从云端只能通过 HTTPS 调用,从设备端可以通过 MQTT 或 AMQP 调用。Direct methods are HTTPS-only from the cloud side, and MQTT or AMQP from the device side.

方法请求和响应的有效负载为最大 128 KB 的 JSON 文档。The payload for method requests and responses is a JSON document up to 128 KB.

从后端应用调用直接方法Invoke a direct method from a back-end app

现在,从后端应用调用某个直接方法。Now, invoke a direct method from a back-end app.

方法调用Method invocation

设备上的直接方法调用是 HTTPS 调用,它由以下项构成:Direct method invocations on a device are HTTPS calls that are made up of the following items:

  • 特定于设备的请求 URI 以及 API 版本The request URI specific to the device along with the API version:

    https://fully-qualified-iothubname.azure-devices.cn/twins/{deviceId}/methods?api-version=2018-06-30
    
  • POST 方法The POST method

  • 标头,包含身份验证、请求 ID、内容类型和内容编码Headers that contain the authorization, request ID, content type, and content encoding

  • 透明的 JSON 正文 ,采用以下格式:A transparent JSON body in the following format:

    {
        "methodName": "reboot",
        "responseTimeoutInSeconds": 200,
        "payload": {
            "input1": "someInput",
            "input2": "anotherInput"
        }
    }
    

超时以秒为单位。Timeout is in seconds. 如果未设置超时,则默认为 30 秒。If timeout is not set, it defaults to 30 seconds.

示例Example

有关使用 curl 的精简示例,请参阅下方。See below for a barebone example using curl.

curl -X POST \
  https://iothubname.azure-devices.cn/twins/myfirstdevice/methods?api-version=2018-06-30 \
  -H 'Authorization: SharedAccessSignature sr=iothubname.azure-devices.cn&sig=x&se=x&skn=iothubowner' \
  -H 'Content-Type: application/json' \
  -d '{
    "methodName": "reboot",
    "responseTimeoutInSeconds": 200,
    "payload": {
        "input1": "someInput",
        "input2": "anotherInput"
    }
}'

响应Response

后端应用接收响应,响应由以下项构成:The back-end app receives a response that is made up of the following items:

  • HTTP 状态代码,用于 IoT 中心发出的错误,包括 404 错误(针对当前未连接的设备)HTTP status code, which is used for errors coming from the IoT Hub, including a 404 error for devices not currently connected

  • 标头,包含 ETag、请求 ID、内容类型和内容编码Headers that contain the ETag, request ID, content type, and content encoding

  • 采用以下格式的 JSON 正文:A JSON body in the following format:

    {
        "status" : 201,
        "payload" : {...}
    }
    

    statusbody 均由设备提供,用于响应,其中包含设备自身的状态代码和/或描述。Both status and body are provided by the device and used to respond with the device's own status code and/or description.

IoT Edge 模块的方法调用Method invocation for IoT Edge modules

IoT 服务客户端 C# SDK 中支持使用模块 ID 调用直接方法。Invoking direct methods using a module ID is supported in the IoT Service Client C# SDK.

为此,请使用 ServiceClient.InvokeDeviceMethodAsync() 方法并传入 deviceIdmoduleId 作为参数。For this purpose, use the ServiceClient.InvokeDeviceMethodAsync() method and pass in the deviceId and moduleId as parameters.

处理针对设备的直接方法Handle a direct method on a device

让我们看看如何在 IoT 设备上处理直接方法。Let's look at how to handle a direct method on an IoT device.

MQTTMQTT

以下部分适用于 MQTT 协议。The following section is for the MQTT protocol.

方法调用Method invocation

设备通过 MQTT 主题接收直接方法请求:$iothub/methods/POST/{method name}/?$rid={request id}Devices receive direct method requests on the MQTT topic: $iothub/methods/POST/{method name}/?$rid={request id}. 每个设备的订阅数限制为 5。The number of subscriptions per device is limited to 5. 因此,建议不要单独订阅每种直接方法。It is therefore recommended not to subscribe to each direct method individually. 而是考虑订阅 $iothub/methods/POST/#,然后根据所需的方法名称筛选传递的消息。Instead consider subscribing to $iothub/methods/POST/# and then filter the delivered messages based on your desired method names.

设备接收的正文采用以下格式:The body that the device receives is in the following format:

{
    "input1": "someInput",
    "input2": "anotherInput"
}

方法请求为 QoS 0。Method requests are QoS 0.

响应Response

设备将响应发送到 $iothub/methods/res/{status}/?$rid={request id},其中:The device sends responses to $iothub/methods/res/{status}/?$rid={request id}, where:

  • status 属性是设备提供的方法执行状态。The status property is the device-supplied status of method execution.
  • $rid 属性是从 IoT 中心接收的方法调用中的请求 ID。The $rid property is the request ID from the method invocation received from IoT Hub.

正文由设备设置,可以是任何状态。The body is set by the device and can be any status.

AMQPAMQP

以下部分适用于 AMQP 协议。The following section is for the AMQP protocol.

方法调用Method invocation

设备通过在地址 amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound 上创建一个接收链接以接收直接方法请求The device receives direct method requests by creating a receive link on address amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound

AMQP 消息会到达表示方法请求的接收链接。The AMQP message arrives on the receive link that represents the method request. 它包含以下部分:It contains the following sections:

  • 相关 ID 属性,其中包含一个应与相应的方法响应被传回的请求 IDThe correlation ID property, which contains a request ID that should be passed back with the corresponding method response
  • 名为 IoThub-methodname 的一个应用程序属性,其中包含调用的方法名称An application property named IoThub-methodname, which contains the name of the method being invoked
  • AMQP 消息正文,其中包含作为 JSON 的方法有效负载The AMQP message body containing the method payload as JSON

响应Response

设备会创建一个发送链接以在 amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound 地址上返回方法响应The device creates a sending link to return the method response on address amqps://{hostname}:5671/devices/{deviceId}/methods/deviceBound

方法的响应在发送链接上返回,并已按以下内容结构化:The method's response is returned on the sending link and is structured as follows:

  • 相关 ID 属性,其中包含在方法的请求消息中传递的请求 IDThe correlation ID property, which contains the request ID passed in the method's request message
  • 名为 IoThub-status 的一个应用程序属性,其中包含用户提供的方法状态An application property named IoThub-status, which contains the user supplied method status
  • AMQP 消息正文,其中包含作为 JSON 的方法响应The AMQP message body containing the method response as JSON

其他参考资料Additional reference material

IoT 中心开发人员指南中的其他参考主题包括:Other reference topics in the IoT Hub developer guide include:

后续步骤Next steps

了解如何使用直接方法后,可根据兴趣参阅以下 IoT 中心开发人员指南文章:Now you have learned how to use direct methods, you may be interested in the following IoT Hub developer guide article:

若要尝试本文中介绍的一些概念,可以根据兴趣学习以下 IoT 中心教程:If you would like to try out some of the concepts described in this article, you may be interested in the following IoT Hub tutorial: