了解和调用 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.


本文介绍的功能仅在 IoT 中心的标准层中可用。The features described in this article are available only in the standard tier of IoT Hub. 有关基本和标准/免费 IoT 中心层的详细信息,请参阅选择合适的 IoT 中心层For more information about the basic and standard/free IoT Hub tiers, see 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).


调用设备上的直接方法时,属性名称和值只能包含 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 秒,可设置为 5 到 300 秒)。Direct methods are synchronous and either succeed or fail after the timeout period (default: 30 seconds, settable between 5 and 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:

  • 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"

在请求中作为 responseTimeoutInSeconds 提供的值是 IoT 中心服务在设备上执行直接方法所需等待的时间。The value provided as responseTimeoutInSeconds in the request is the amount of time that IoT Hub service must await for completion of a direct method execution on a device. 将此超时设置为至少与设备的直接方法的预期执行时间一样长。Set this timeout to be at least as long as the expected execution time of a direct method by a device. 如果未提供超时,则使用默认值:30 秒。If timeout is not provided, it the default value of 30 seconds is used. responseTimeoutInSeconds 的最小值和最大值分别为 5 秒和 300 秒。The minimum and maximum values for responseTimeoutInSeconds are 5 and 300 seconds, respectively.

在请求中作为 connectTimeoutInSeconds 提供的值是在调用直接方法后,IoT 中心服务等待断开连接的服务进入联机状态所需的时间。The value provided as connectTimeoutInSeconds in the request is the amount of time upon invocation of a direct method that IoT Hub service must await for a disconnected device to come online. 默认值为 0,表示在调用直接方法时,设备必须已处于联机状态。The default value is 0, meaning that devices must already be online upon invocation of a direct method. connectTimeoutInSeconds 的最大值为 300 秒。The maximum value for connectTimeoutInSeconds is 300 seconds.


此示例将允许你安全地发起请求,以调用已注册到 Azure IoT 中心的 IoT 设备上的直接方法。This example will allow you to securely initiate a request to invoke a Direct Method on an IoT device registered to an Azure IoT Hub.

若要开始,请使用适用于 Azure CLI 的 Microsoft Azure IoT 扩展创建 SharedAccessSignature。To begin, use the Microsoft Azure IoT extension for Azure CLI to create a SharedAccessSignature.

az iot hub generate-sas-token -n <iothubName> -du <duration>

接下来,将 Authorization 标头替换为新生成的 SharedAccessSignature,然后修改 iothubNamedeviceIdmethodNamepayload 参数,使之与下面的示例 curl 命令中的实现匹配。Next, replace the Authorization header with your newly generated SharedAccessSignature, then modify the iothubName, deviceId, methodName and payload parameters to match your implementation in the example curl command below.

curl -X POST \
  https://<iothubName>.azure-devices.cn/twins/<deviceId>/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"

执行修改后的命令以调用指定的直接方法。Execute the modified command to invoke the specified Direct Method. 成功的请求将返回 HTTP 200 状态代码。Successful requests will return an HTTP 200 status code.


上面的示例演示如何调用设备上的直接方法。The above example demonstrates invoking a Direct Method on a device. 若要调用 IoT Edge 模块中的直接方法,需要修改 URL 请求,如下所示:If you wish to invoke a Direct Method in an IoT Edge Module, you would need to modify the url request as shown below:



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

  • HTTP 状态代码:HTTP status code:

    • 200 表示成功执行直接方法;200 indicates successful execution of direct method;
    • 404 表示设备 ID 无效,或者设备在调用直接方法后 connectTimeoutInSeconds 秒内未联机(请使用伴随的错误消息来了解根本原因);404 indicates that either device ID is invalid, or that the device was not online upon invocation of a direct method and for connectTimeoutInSeconds thereafter (use accompanied error message to understand the root cause);
    • 504 表示由于设备在 responseTimeoutInSeconds 秒内未响应直接方法调用而导致网关超时。504 indicates gateway timeout caused by device not responding to a direct method call within responseTimeoutInSeconds.
  • 标头,包含 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.


以下部分适用于 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.


设备将响应发送到 $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.


以下部分适用于 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


设备会创建一个发送链接以在 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: