使用.Net Device SDK从设备上向Azure IoT Hub上传文件
分类: Azure物联网 ◆ 标签: #Azure #IoT Hub # ◆ 发布于: 2023-06-13 20:51:56

如果需要从设备上向IoT Hub上传文件,首先需要配置文件上传的功能,也需要创建一个和Azure IoT Hub
在同一个区域的Storage Account
, 关于如何创建Storage Account
和blob
, 您可以参考文档:https://docs.microsoft.com/zh-cn/azure/storage/common/storage-account-create?tabs=azure-portal, 创建好之后找到您的Azure IoT Hub
, 从左边找到File Upload
这个功能,进行配置,如下图:
配置好了之后就,保存退出,然后我们开始使用.Net Device SDK
从设备上向IoT Hub上传文件。
创建一个新的项目
首先使用如下的命令取得设备simDevice
的连接字符串,当然这之前你需要先创建好Azure IoT Hub
资源以及该设备:
az iot hub device-identity connection-string show --device-id simDevice --hub-name MyIoThubByCli
得到连接字符串之后,先保存起来,后面的代码中需要使用到这个连接字符串。
使用下述的命令创建我们的项目:
dotnet new console -o FileUploadSample
cd FileUploadSample
dotnet add package Microsoft.Azure.Devices.Client
dotnet add package Azure.Storage.Blobs
code .
打开VS code
或者其他编辑器之后,在根目录下添加一个文件GlobalUsing.cs
, 打开该文件,添加如下的引用:
global using Microsoft.Azure.Devices.Client; global using System.Text.Json; global using System.Text; global using System.Text.Json.Serialization; global using System.Diagnostics; global using Microsoft.Azure.Devices.Shared; global using Azure.Storage.Blobs.Models; global using Azure.Storage.Blobs.Specialized; global using FileUploadSample;
在根目录下创建一个UploadSample.cs
的文件,以下述内容替换:
namespace FileUploadSample; public class UploadSample { private readonly DeviceClient _deviceClient; public UploadSample(DeviceClient deviceClient) { _deviceClient = deviceClient; } public async Task RunSampleAsync() { const string filePath = "TestPayload.txt"; using var fileStreamSource = new FileStream(filePath, FileMode.Open); var fileName = Path.GetFileName(fileStreamSource.Name); Console.WriteLine($"上传文件: {fileName}"); var fileUploadTime = Stopwatch.StartNew(); var fileUploadSasUriRequest = new FileUploadSasUriRequest { BlobName = fileName }; // Note: GetFileUploadSasUriAsync and CompleteFileUploadAsync will use HTTPS as protocol regardless of the DeviceClient protocol selection. Console.WriteLine("取得SAS URL, 用于上传,要预先配置file upload。"); FileUploadSasUriResponse sasUri = await _deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest); Uri uploadUri = sasUri.GetBlobUri(); Console.WriteLine($"成功从IoT Hub中取得SAS URI:{uploadUri}"); try { Console.WriteLine($"使用Azure Storage SDK 和取得的SAS URI上传文件: {fileName} "); var blockBlobClient = new BlockBlobClient(uploadUri); await blockBlobClient.UploadAsync(fileStreamSource, new BlobUploadOptions()); } catch (Exception ex) { Console.WriteLine($"上传失败: {ex}"); var failedFileUploadCompletionNotification = new FileUploadCompletionNotification { CorrelationId = sasUri.CorrelationId, IsSuccess = false, StatusCode = 500, StatusDescription = ex.Message }; //使用Azure Stoarege SDK上传完之后,必须要释放URI, IoT Hub的SAS URI对多少个设备可以上传文件有限制。 //同时上传完了之后,还会给IoT Hub发通知。 await _deviceClient.CompleteFileUploadAsync(failedFileUploadCompletionNotification); Console.WriteLine("通知IoT Hub上传失败,可以释放SAS URI"); fileUploadTime.Stop(); return; } Console.WriteLine("成功上传至Azure Storage"); var successfulFileUploadCompletionNotification = new FileUploadCompletionNotification { CorrelationId = sasUri.CorrelationId, IsSuccess = true, StatusCode = 200, StatusDescription = "Success" }; //同样需要调用完成的方法,释放SAS URI await _deviceClient.CompleteFileUploadAsync(successfulFileUploadCompletionNotification); Console.WriteLine("通知IoT Hub上传成功,并释放SAS URI"); fileUploadTime.Stop(); Console.WriteLine($"上传文件时间: {fileUploadTime.Elapsed}."); } }
需要注意的是:
- 文件上传的实际动作还是由
Azure Storage SDK
完成。 Storage
上传的SAS URI是由Azure IoT Hub
提供。Azure IoT Hub
对SAS URI
可使用的设备数有限制,因此无论上传成功还是失败,都要及时释放。- 注意如何释放SAS URI的。
打开Program.cs
, 使用如下的内容替换:
Console.WriteLine("使用SAS Key连接字符串连接Azure IoT Hub, 从设备上上传文件:"); string s_connectionString = "HostName=MyIoTHubByCli.azure-devices.cn;DeviceId=simDevice;SharedAccessKey=WyuzYpZa7ekyaAp/6bJlccOgzCHc7KwDNZ56d26jiHY="; //验证连接字符串是否是正确的 ValidateConnectionString(args); DeviceClient s_deviceClient = DeviceClient.CreateFromConnectionString(s_connectionString); using var deviceClient = DeviceClient.CreateFromConnectionString( s_connectionString, TransportType.Mqtt); var sample = new UploadSample(deviceClient); await sample.RunSampleAsync(); await deviceClient.CloseAsync(); Console.WriteLine("Done."); void ValidateConnectionString(string[] appArgs) { if ( appArgs.Any() ) { try { var cs = IotHubConnectionStringBuilder.Create(appArgs[0]); s_connectionString = cs.ToString(); } catch ( Exception ) { Console.WriteLine($"错误:无法识别连接字符串参数 `{appArgs[0]}"); Environment.Exit(-1); } } else { try { _ = IotHubConnectionStringBuilder.Create(s_connectionString); } catch(Exception ) { Console.WriteLine("这个Demo需要使用连接字符串连接到Azure IoT Hub"); Environment.Exit(-1); } } }