如何使用C#脚本触发Azure Function向IoT Hub发送C2D消息
C# 实现 Azure Function 向 IoT Hub 设备发送 C2D 控制指令方案
前置准备
- Azure Function 项目引入NuGet包
Microsoft.Azure.Devices,这是IoT Hub官方服务端SDK,封装了C2D消息发送的全部接口 - 在Function应用配置中存入IoT Hub服务端连接字符串(需绑定
Service Connect权限,不要误用设备级连接字符串),目标设备ID可随触发参数传入,无需硬编码
核心实现代码
以下是HTTP触发的Function示例,支持通过脚本调用触发,核心发送逻辑可复用到定时器、队列触发等其他触发场景:
using System; using System.Text; using Microsoft.Azure.Devices; using Microsoft.AspNetCore.Mvc; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Extensions.Http; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; public static class SendC2DControlCommand { private static readonly string iotHubConnStr = Environment.GetEnvironmentVariable("IoTHubServiceConnectionString"); private static readonly ServiceClient iotHubServiceClient = ServiceClient.CreateFromConnectionString(iotHubConnStr); [FunctionName("SendDeviceControlCmd")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log) { log.LogInformation("C2D控制指令发送触发"); string requestContent = await new StreamReader(req.Body).ReadToEndAsync(); dynamic requestParams = JsonConvert.DeserializeObject(requestContent); string targetDeviceId = requestParams?.targetDeviceId; string command = requestParams?.command?.ToString().ToUpper(); // 参数合法性校验 if (string.IsNullOrEmpty(targetDeviceId) || (command != "ON" && command != "OFF" && command != "HIGH" && command != "LOW")) { return new BadRequestObjectResult("请求需传入合法的targetDeviceId,以及ON/OFF/HIGH/LOW其中一种控制指令"); } try { // 组装C2D消息 Message cmdMessage = new Message(Encoding.UTF8.GetBytes(command)); // 添加自定义消息属性,设备端可直接读取属性无需解析正文 cmdMessage.Properties.Add("msgType", "deviceControl"); // 设置消息过期时间,控制指令建议设短TTL,避免设备上线收到过期指令 cmdMessage.TimeToLive = TimeSpan.FromMinutes(1); // 向目标设备发送消息 await iotHubServiceClient.SendAsync(targetDeviceId, cmdMessage); log.LogInformation($"已向设备{targetDeviceId}发送控制指令:{command}"); return new OkObjectResult($"指令{command}已成功下发至设备{targetDeviceId}"); } catch (Exception ex) { log.LogError($"C2D消息发送失败:{ex.Message}"); return new StatusCodeResult(StatusCodes.Status500InternalServerError); } } }
关键注意事项
- 消息TTL设置:ON/OFF、HIGH/LOW这类实时控制指令不要设置过长存活时间,C2D消息最长支持48小时TTL,控制类场景建议设为1分钟以内
- 权限校验:HTTP触发接口保持默认的
Function级别授权校验,不要开启匿名访问,避免被恶意调用下发非法指令 - 设备端配套逻辑:设备端收到C2D消息后需要向IoT Hub回传接收确认,否则IoT Hub会判定消息未送达,触发重发逻辑
脚本调用示例
用C#脚本触发Function时,直接向Function的触发地址发POST请求即可,请求体格式参考:
{ "targetDeviceId": "relay-device-012", "command": "ON" }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

