你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
使用 Azure IoT 中心将文件从设备上传到云
本文演示了以下内容的操作方法:
- 使用 IoT 中心的文件上传功能,通过 Azure IoT 设备和服务 SDK 将文件上传到 Azure Blob 存储。
- 通知 IoT 中心文件已成功上传,并创建后端服务,以使用 Azure IoT 服务 SDK 从 IoT 中心接收文件上传通知。
在某些情况下,无法轻松地将设备发送的数据映射为 IoT 中心接受的相对较小的设备到云消息。 借助 IoT 中心中的文件上传功能,可以将大型或复杂数据移到云中。 例如:
- 视频
- 包含图像的大型文件
- 以高频率采样的振动数据
- 某种形式的预处理数据
通常使用 Azure 数据工厂或 Hadoop 堆栈等工具在云中批处理这些文件。 需要从设备上传文件时,仍可以使用 IoT 中心的安全性和可靠性。 本文介绍如何进行此操作。
本文旨在补充本文中引用的可运行 SDK 示例。
有关详细信息,请参阅:
重要
使用 X.509 证书颁发机构 (CA) 身份验证的设备上的文件上传功能为公共预览版,并且必须启用预览模式。 这是在一同使用 X.509 指纹身份验证或 X.509 证书证明与 Azure 设备预配服务的设备上的正式发布版本。 若要了解有关使用 IoT 中心进行 X.509 身份验证的详细信息,请参阅支持的 X.509 证书。
先决条件
IoT 中心。 某些 SDK 调用需要 IoT 中心主连接字符串,因此请记下连接字符串。
已注册的设备。 某些 SDK 调用需要设备主连接字符串,因此请记下连接字符串。
IoT 中心服务连接权限 - 若要接收文件上传通知消息,后端服务需要“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。 有关详细信息,请参阅连接到 IoT 中心。
通过链接 Azure 存储帐户和 Azure Blob 存储容器,在 IoT 中心配置文件上传。 可以使用 Azure 门户、Azure CLI 或 Azure PowerShell 进行配置。
概述
本操作说明包含两个部分:
- 从设备应用程序上传文件
- 在后端应用程序中接收文件上传通知
从设备应用程序上传文件
本部分介绍如何使用适用于 .NET 的 Azure IoT SDK 中的 DeviceClient 类将文件从设备上传到 IoT 中心。
按照此过程将文件从设备上传到 IoT 中心:
- 连接到 IoT 中心
- 从 IoT 中心获取 SAS URI
- 将文件上传到 Azure 存储
- 通知 IoT 中心文件上传状态
将设备连接到 IoT 中心
设备应用可以使用以下方法向 IoT 中心进行身份验证:
- X.509 证书
- 共享访问密钥
使用 X.509 证书进行身份验证
使用 X.509 证书将设备连接到 IoT 中心:
使用 DeviceAuthenticationWithX509Certificate 创建包含设备和证书信息的对象。
DeviceAuthenticationWithX509Certificate
将作为第二个参数传递给DeviceClient.Create
(步骤 2)。使用 DeviceClient.Create 通过 X.509 证书将设备连接到 IoT 中心。
在此示例中,设备和证书信息将填充在传递给 DeviceClient.Create
的 auth
DeviceAuthenticationWithX509Certificate
对象中。
清楚起见,此示例以本地变量的形式显示证书输入参数值。 在生产系统中,请将敏感输入参数存储在环境变量中或其他更安全的存储位置。 例如,使用 Environment.GetEnvironmentVariable("HOSTNAME")
读取主机名环境变量。
RootCertPath = "~/certificates/certs/sensor-thl-001-device.cert.pem";
Intermediate1CertPath = "~/certificates/certs/sensor-thl-001-device.intermediate1.cert.pem";
Intermediate2CertPath = "~/certificates/certs/sensor-thl-001-device.intermediate2.cert.pem";
DevicePfxPath = "~/certificates/certs/sensor-thl-001-device.cert.pfx";
DevicePfxPassword = "1234";
DeviceName = "MyDevice";
HostName = "xxxxx.azure-devices.net";
var chainCerts = new X509Certificate2Collection();
chainCerts.Add(new X509Certificate2(RootCertPath));
chainCerts.Add(new X509Certificate2(Intermediate1CertPath));
chainCerts.Add(new X509Certificate2(Intermediate2CertPath));
using var deviceCert = new X509Certificate2(DevicePfxPath, DevicePfxPassword);
using var auth = new DeviceAuthenticationWithX509Certificate(DeviceName, deviceCert, chainCerts);
using var deviceClient = DeviceClient.Create(
HostName,
auth,
TransportType.Amqp);
有关证书身份验证的详细信息,请参阅:
代码示例
有关设备 X.509 证书身份验证的工作示例,请参阅:
使用共享访问密钥进行身份验证
调用 CreateFromConnectionString 以连接到设备。 传递设备主连接字符串。
AMQP
是默认传输协议。
static string connectionString = "{device primary connection string}";
deviceClient = DeviceClient.CreateFromConnectionString(connectionString);
从 IoT 中心获取 SAS URI
调用 GetFileUploadSasUriAsync 以获取文件上传详细信息。 下一步使用 SAS URI 将文件从设备上传到 Blob 存储。
const string filePath = "TestPayload.txt";
using var fileStreamSource = new FileStream(filePath, FileMode.Open);
var fileName = Path.GetFileName(fileStreamSource.Name);
var fileUploadSasUriRequest = new FileUploadSasUriRequest
{
BlobName = fileName
};
FileUploadSasUriResponse sasUri = await _deviceClient.GetFileUploadSasUriAsync(fileUploadSasUriRequest, System.Threading.CancellationToken cancellationToken = default);
Uri uploadUri = sasUri.GetBlobUri();
将文件上传到 Azure 存储
将文件上传到 Azure 存储:
创建 blockBlobClient 对象,并传递文件上传 URI。
使用 UploadAsync 方法将文件上传到 Blob 存储,并传递 SAS URI。 可以选择性地添加 Blob 上传选项和取消令牌参数。
Azure Blob 客户端始终使用 HTTPS 作为协议来将文件上传到 Azure 存储。
在此示例中,将 SAS URI 传递给 BlockBlobClient
,以创建 Azure 存储块 Blob 客户端并上传文件:
var blockBlobClient = new BlockBlobClient(uploadUri);
await blockBlobClient.UploadAsync(fileStreamSource, null, null);
通知 IoT 中心文件上传状态
使用 CompleteFileUploadAsync 通知 IoT 中心设备客户端已完成上传,并传递 FileUploadCompletionNotification 对象。 该 IsSuccess
标志指示上传是否成功。 收到通知后,IoT 中心将释放与上传关联的资源 (SAS URI)。
如果启用了文件上传通知,IoT 中心会将文件上传通知消息发送到为文件上传通知配置的后端服务。
var successfulFileUploadCompletionNotification = new FileUploadCompletionNotification
{
// Mandatory. Must be the same value as the correlation id returned in the sas uri response
CorrelationId = sasUri.CorrelationId,
// Mandatory. Will be present when service client receives this file upload notification
IsSuccess = true,
// Optional, user defined status code. Will be present when service client receives this file upload notification
StatusCode = 200,
// Optional, user-defined status description. Will be present when service client receives this file upload notification
StatusDescription = "Success"
};
await _deviceClient.CompleteFileUploadAsync(successfulFileUploadCompletionNotification);
SDK 文件上传示例
SDK 包含此文件上传示例。
在后端应用程序中接收文件上传通知
创建一项后端服务,用于从 IoT 中心接收文件上传通知消息。
ServiceClient 类包含服务可用于接收文件上传通知的方法。
添加服务 NuGet 包
后端服务应用程序需要 NuGet 包“Microsoft.Azure.Devices”。
连接到 IoT 中心
可使用以下方法将后端服务连接到 IoT 中心:
- 共享访问策略
- Microsoft Entra
重要
本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全。
使用共享访问策略进行连接
使用 CreateFromConnectionString 将后端应用程序连接到设备。 你的应用程序需要“服务连接”权限。 将此共享访问策略连接字符串作为参数提供给 fromConnectionString
。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问。
例如:
using Microsoft.Azure.Devices;
static ServiceClient serviceClient;
static string connectionString = "{Shared access policy connection string}";
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
使用 Microsoft Entra 进行连接
使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问。
配置 Microsoft Entra 应用
必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:
- 客户端机密
- 证书
- 联合标识凭据
根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问。
有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台。
使用 DefaultAzureCredential 进行身份验证
使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential
或精简的 ChainedTokenCredential
。 为简单起见,本部分介绍如何使用 DefaultAzureCredential
和客户端机密进行身份验证。 有关使用 DefaultAzureCredential
的利弊的详细信息,请参阅 DefaultAzureCredential 的使用指南。
DefaultAzureCredential
支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。
Microsoft Entra 需要这些 NuGet 包和相应的 using
语句:
- Azure.Core
- Azure.Identity
using Azure.Core;
using Azure.Identity;
在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 将添加到环境变量中。 DefaultAzureCredential
使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。
string clientSecretValue = "xxxxxxxxxxxxxxx";
string clientID = "xxxxxxxxxxxxxx";
string tenantID = "xxxxxxxxxxxxx";
Environment.SetEnvironmentVariable("AZURE_CLIENT_SECRET", clientSecretValue);
Environment.SetEnvironmentVariable("AZURE_CLIENT_ID", clientID);
Environment.SetEnvironmentVariable("AZURE_TENANT_ID", tenantID);
TokenCredential tokenCredential = new DefaultAzureCredential();
然后可以将生成的 TokenCredential 传递给任何接受 Microsoft Entra 凭据的 SDK 客户端的 IoT 中心连接方法:
在此示例中,TokenCredential
将传递给 ServiceClient.Create
,以创建 ServiceClient 连接对象。
string hostname = "xxxxxxxxxx.azure-devices.net";
using var serviceClient = ServiceClient.Create(hostname, tokenCredential, TransportType.Amqp);
在此示例中,TokenCredential
将传递给 RegistryManager.Create
,以创建 RegistryManager 对象。
string hostname = "xxxxxxxxxx.azure-devices.net";
registryManager = RegistryManager.Create(hostname, tokenCredential);
代码示例
有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例。
接收文件上传通知
接收文件上传通知:
- 创建 CancellationToken。
- 调用 GetFileNotificationReceiver 来创建通知接收方。
- 将循环与 ReceiveAsync 一起使用,等待文件上传通知。
例如:
// Define the cancellation token
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
// Create a notification receiver
var notificationReceiver = serviceClient.GetFileNotificationReceiver();
Console.WriteLine("\nReceiving file upload notification from service");
// Check for file upload notifications
while (true)
{
var fileUploadNotification = await notificationReceiver.ReceiveAsync(token);
if (fileUploadNotification == null) continue;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Received file upload notification: {0}",
string.Join(", ", fileUploadNotification.BlobName));
Console.ResetColor();
await notificationReceiver.CompleteAsync(fileUploadNotification);
}
SDK 文件上传接收器示例
SDK 包含此文件上传接收器示例。
概述
本操作说明包含两个部分:
- 从设备应用程序上传文件
- 在后端应用程序中接收文件上传通知
从设备应用程序上传文件
本部分介绍如何使用适用于 Java 的 Azure IoT SDK 中的 DeviceClient 类将文件从设备上传到 IoT 中心。
按照此过程将文件从设备上传到 IoT 中心:
- 将设备连接到 IoT 中心
- 从 IoT 中心获取 SAS URI
- 将文件上传到 Azure 存储
- 将文件上传状态通知发送到 IoT 中心
将设备连接到 IoT 中心
设备应用可以使用以下方法向 IoT 中心进行身份验证:
- X.509 证书
- 共享访问密钥
使用 X.509 证书进行身份验证
使用 X.509 证书将设备连接到 IoT 中心:
- 使用 buildSSLContext 生成 SSLContext 对象。
- 将
SSLContext
信息添加到 ClientOptions 对象。 - 使用
ClientOptions
信息调用 DeviceClient,以创建设备到 IoT 中心的连接。
清楚起见,此示例以本地变量的形式显示证书输入参数值。 在生产系统中,请将敏感输入参数存储在环境变量中或其他更安全的存储位置。 例如,使用 Environment.GetEnvironmentVariable("PUBLICKEY")
读取公钥证书字符串环境变量。
private static final String publicKeyCertificateString =
"-----BEGIN CERTIFICATE-----\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"-----END CERTIFICATE-----\n";
//PEM encoded representation of the private key
private static final String privateKeyString =
"-----BEGIN EC PRIVATE KEY-----\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n" +
"-----END EC PRIVATE KEY-----\n";
SSLContext sslContext = SSLContextBuilder.buildSSLContext(publicKeyCertificateString, privateKeyString);
ClientOptions clientOptions = ClientOptions.builder().sslContext(sslContext).build();
DeviceClient client = new DeviceClient(connString, protocol, clientOptions);
有关证书身份验证的详细信息,请参阅:
代码示例
有关设备 X.509 证书身份验证的工作示例,请参阅:
使用共享访问密钥进行身份验证
文件上传操作始终使用 HTTPS,但 DeviceClient 可以为遥测、设备方法和设备孪生等其他服务定义 IotHubClientProtocol。
IotHubClientProtocol protocol = IotHubClientProtocol.MQTT;
实例化 DeviceClient
,以使用设备主连接字符串连接到设备。
String connString = "{IoT hub connection string}";
DeviceClient client = new DeviceClient(connString, protocol);
从 IoT 中心获取 SAS URI
调用 getFileUploadSasUri 以获取 FileUploadSasUriResponse 对象。
FileUploadSasUriResponse
包括这些方法和返回值。 可以将返回值传递给文件上传方法。
方法 | 返回值 |
---|---|
getCorrelationId() |
相关 ID |
getContainerName() |
容器名称 |
getBlobName() |
Blob 名称 |
getBlobUri() |
Blob URI |
例如:
FileUploadSasUriResponse sasUriResponse = client.getFileUploadSasUri(new FileUploadSasUriRequest(file.getName()));
System.out.println("Successfully got SAS URI from IoT hub");
System.out.println("Correlation Id: " + sasUriResponse.getCorrelationId());
System.out.println("Container name: " + sasUriResponse.getContainerName());
System.out.println("Blob name: " + sasUriResponse.getBlobName());
System.out.println("Blob Uri: " + sasUriResponse.getBlobUri());
将文件上传到 Azure 存储
将 blob URI 终结点传递给 BlobClientBuilder.buildclient ,以创建 BlobClient 对象。
BlobClient blobClient =
new BlobClientBuilder()
.endpoint(sasUriResponse.getBlobUri().toString())
.buildClient();
调用 uploadFromFile 将文件上传到 Blob 存储。
String fullFileName = "Path of the file to upload";
blobClient.uploadFromFile(fullFileName);
将文件上传状态通知发送到 IoT 中心
尝试文件上传后,将上传状态通知发送到 IoT 中心。
创建 FileUploadCompletionNotification 对象。 传递 correlationId
和 isSuccess
文件上传成功状态。 成功上传文件时传递 isSuccess
true
值,未成功上传文件时传递 false
。
即使文件上传失败,也必须调用 FileUploadCompletionNotification
。 IoT 中心具有固定数量的 SAS URI,它们可以在任何给定时间处于活动状态。 完成文件上传后,应释放 SAS URI,以便生成其他 SAS URI。 如果 SAS URI 未通过此 API 释放,则它最终会根据在 IoT 中心上配置的 SAS URI 存活时间来释放自己。
此示例传递成功状态。
FileUploadCompletionNotification completionNotification = new FileUploadCompletionNotification(sasUriResponse.getCorrelationId(), true);
client.completeFileUpload(completionNotification);
关闭客户端
释放 client
资源。
client.closeNow();
创建后端应用程序
本部分介绍如何在后端应用程序中接收文件上传通知。
ServiceClient 类包含服务可用于接收文件上传通知的方法。
添加 import 语句
添加这些 import 语句以使用 Azure IoT Java SDK 和异常处理程序。
import com.microsoft.azure.sdk.iot.service.*;
import java.io.IOException;
import java.net.URISyntaxException;
连接到 IoT 中心
可以使用以下方法将后端服务连接到 IoT 中心:
- 共享访问策略
- Microsoft Entra
重要
本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全。
使用共享访问策略进行连接
定义连接协议
使用 IotHubServiceClientProtocol 定义服务客户端与 IoT 中心通信所使用的应用层协议。
IotHubServiceClientProtocol
仅接受 AMQPS
或 AMQPS_WS
枚举。
private static final IotHubServiceClientProtocol protocol =
IotHubServiceClientProtocol.AMQPS;
创建 ServiceClient 对象
创建 ServiceClient 对象,提供 Iot 中心连接字符串和协议。
若要将设备上的文件上传到 IoT 中心,你的服务需要具有“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。
以 ServiceClient
构造函数的参数形式,提供服务共享访问策略。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问。
String iotHubConnectionString = "HostName=xxxxx.azure-devices.net;SharedAccessKeyName=service;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxx";
private static final ServiceClient serviceClient (iotHubConnectionString, protocol);
打开应用程序与 IoT 中心之间的连接
使用 open 方法打开 AMQP 发送器连接。 此方法会创建应用程序与 IoT 中心之间的连接。
serviceClient.open();
使用 Microsoft Entra 进行连接
使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问。
有关 Java SDK 身份验证的概述,请参阅使用 Java 和 Azure 标识进行 Azure 身份验证。
为简单起见,本部分重点介绍如何使用客户端机密进行身份验证。
配置 Microsoft Entra 应用
必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:
- 客户端机密
- 证书
- 联合标识凭据
根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问。
有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台。
使用 DefaultAzureCredential 进行身份验证
使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential
或精简的 ChainedTokenCredential
。
有关使用 DefaultAzureCredential
的利弊的详细信息,请参阅适用于 Java 的 Azure 标识客户端库中的凭据链。
DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。
可以使用 DefaultAzureCredentialBuilder 来验证 Microsoft Entra 应用凭据。 客户端机密 tenantID、clientID 和客户端机密值等连接参数将保存为环境变量。 创建 TokenCredential
后,请将其作为“credential”参数传递给 ServiceClient 或其他生成器。
在此示例中,DefaultAzureCredentialBuilder
尝试根据 DefaultAzureCredential 中描述的列表对连接进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 ServiceClient 等构造函数的安全令牌凭据。
TokenCredential defaultAzureCredential = new DefaultAzureCredentialBuilder().build();
使用 ClientSecretCredentialBuilder 进行身份验证
可以使用 ClientSecretCredentialBuilder 来创建使用客户端机密信息的凭据。 如果成功,此方法将返回 TokenCredential,可将其作为“credential”参数传递给 ServiceClient 或其他生成器。
在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 值已添加到环境变量中。 ClientSecretCredentialBuilder
使用这些环境变量来生成凭据。
string clientSecretValue = System.getenv("AZURE_CLIENT_SECRET");
string clientID = System.getenv("AZURE_CLIENT_ID");
string tenantID = System.getenv("AZURE_TENANT_ID");
TokenCredential credential =
new ClientSecretCredentialBuilder()
.tenantId(tenantID)
.clientId(clientID)
.clientSecret(clientSecretValue)
.build();
其他身份验证类
Java SDK 还包括以下使用 Microsoft Entra 对后端应用程序进行身份验证的类:
- AuthorizationCodeCredential
- AzureCliCredential
- AzureDeveloperCliCredential
- AzurePipelinesCredential
- ChainedTokenCredential
- ClientAssertionCredential
- ClientCertificateCredential
- DeviceCodeCredential
- EnvironmentCredential
- InteractiveBrowserCredential
- ManagedIdentityCredential
- OnBehalfOfCredential
代码示例
有关 Microsoft Entra 服务身份验证的有效示例,请参阅基于角色的身份验证示例。
检查文件上传状态
检查文件上传状态:
- 创建 getFileUploadNotificationReceiver 对象。
- 使用 open 连接到 IoT 中心。
- 调用 receive 以检查文件上传状态。 此方法返回 fileUploadNotification 对象。 如果收到上传通知,可以使用 fileUploadNotification 方法查看上传状态字段。
例如:
FileUploadNotificationReceiver receiver = serviceClient.getFileUploadNotificationReceiver();
receiver.open();
FileUploadNotification fileUploadNotification = receiver.receive(2000);
if (fileUploadNotification != null)
{
System.out.println("File Upload notification received");
System.out.println("Device Id : " + fileUploadNotification.getDeviceId());
System.out.println("Blob Uri: " + fileUploadNotification.getBlobUri());
System.out.println("Blob Name: " + fileUploadNotification.getBlobName());
System.out.println("Last Updated : " + fileUploadNotification.getLastUpdatedTimeDate());
System.out.println("Blob Size (Bytes): " + fileUploadNotification.getBlobSizeInBytes());
System.out.println("Enqueued Time: " + fileUploadNotification.getEnqueuedTimeUtcDate());
}
else
{
System.out.println("No file upload notification");
}
// Close the receiver object
receiver.close();
SDK 文件上传示例
有两个 Java 文件上传示例。
安装包
必须先安装 azure-iot-device 库,然后才能调用任何相关代码。
pip install azure-iot-device
azure.storage.blob 包用于执行文件上传。
pip install azure.storage.blob
从设备应用程序上传文件
本部分介绍如何使用适用于 Python 的 Azure IoT SDK 中的 IoTHubDeviceClient 类将文件从设备上传到 IoT 中心。
导入库
import os
from azure.iot.device import IoTHubDeviceClient
from azure.core.exceptions import AzureError
from azure.storage.blob import BlobClient
将设备连接到 IoT 中心
设备应用可以使用以下方法向 IoT 中心进行身份验证:
- X.509 证书
- 共享访问密钥
使用 X.509 证书进行身份验证
使用 X.509 证书将设备连接到 IoT 中心:
- 使用 create_from_x509_certificate 添加 X.509 证书参数
- 调用 connect 以连接设备客户端
清楚起见,此示例以本地变量的形式显示证书输入参数值。 在生产系统中,请将敏感输入参数存储在环境变量中或其他更安全的存储位置。 例如,使用 os.getenv("HOSTNAME")
读取主机名环境变量。
# The Azure IoT hub name
hostname = "xxxxx.azure-devices.net"
# The device that has been created on the portal using X509 CA signing or self-signing capabilities
device_id = "MyDevice"
# The X.509 certificate file name
cert_file = "~/certificates/certs/sensor-thl-001-device.cert.pfx"
key_file = "~/certificates/certs/sensor-thl-001-device.cert.key"
# The optional certificate pass phrase
pass_phrase = "1234"
x509 = X509(
cert_file,
key_file,
pass_phrase,
)
# The client object is used to interact with your Azure IoT hub.
device_client = IoTHubDeviceClient.create_from_x509_certificate(
hostname=hostname, device_id=device_id, x509=x509
)
# Connect to IoT Hub
await device_client.connect()
有关证书身份验证的详细信息,请参阅:
代码示例
有关设备 X.509 证书身份验证的工作示例,请参阅异步中心场景中文件名以 x509 结尾的示例。
使用共享访问密钥进行身份验证
将设备连接到 IoT 中心:
- 调用 create_from_connection_string,以添加设备主连接字符串。
- 调用 connect 以连接设备客户端。
例如:
# Add your IoT hub primary connection string
CONNECTION_STRING = "{Device primary connection string}"
device_client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
# Connect the client
device_client.connect()
获取 Blob 存储信息
调用 get_storage_info_for_blob,从 IoT 中心获取有关链接的 Azure 存储帐户的信息。 此信息包括主机名、容器名称、blob 名称和 SAS 令牌。 get_storage_info_for_blob
方法还返回在 notify_blob_upload_status
方法中使用的 correlation_id
。 IoT 中心使用 correlation_id
来标记你在处理的 Blob。
# Get the storage info for the blob
PATH_TO_FILE = "{Full path to local file}"
blob_name = os.path.basename(PATH_TO_FILE)
blob_info = device_client.get_storage_info_for_blob(blob_name)
将文件上传到 Blob 存储
若要将文件上传到 Blob 存储,请执行以下操作:
- 使用 from_blob_url 从 Blob URL 创建 BlobClient 对象。
- 调用 upload_blob 将文件上传到 Blob 存储。
此示例分析 blob_info
结构,以创建用于初始化 BlobClient 的 URL。 然后,它会调用 upload_blob
将文件上传到 Blob 存储。
try:
sas_url = "https://{}/{}/{}{}".format(
blob_info["hostName"],
blob_info["containerName"],
blob_info["blobName"],
blob_info["sasToken"]
)
print("\nUploading file: {} to Azure Storage as blob: {} in container {}\n".format(file_name, blob_info["blobName"], blob_info["containerName"]))
# Upload the specified file
with BlobClient.from_blob_url(sas_url) as blob_client:
with open(file_name, "rb") as f:
result = blob_client.upload_blob(f, overwrite=True)
return (True, result)
except FileNotFoundError as ex:
# catch file not found and add an HTTP status code to return in notification to IoT hub
ex.status_code = 404
return (False, ex)
except AzureError as ex:
# catch Azure errors that might result from the upload operation
return (False, ex)
通知 IoT 中心上传状态
使用 notify_blob_upload_status 通知 IoT 中心 Blob 存储操作的状态。 传递 get_storage_info_for_blob
方法获取的 correlation_id
。 IoT 中心使用 correlation_id
来通知任何可能正在侦听文件上传任务状态通知的服务。
此示例通知 IoT 中心已成功上传文件:
device_client.notify_blob_upload_status(storage_info["correlationId"], True, 200, "OK: {}".format(PATH_TO_FILE)
关闭设备客户端
关闭客户端。 调用此方法后,尝试进一步调用客户端会导致引发 ClientError。
device_client.shutdown()
SDK 文件上传示例
SDK 包含两个文件上传示例:
概述
本文介绍如何使用 Azure IoT SDK for Node.js 创建用于上传文件的设备应用,以及用于接收文件上传通知的后端服务应用程序。
创建设备应用程序
本部分介绍如何使用适用于 Node.js 的 Azure IoT SDK 中的 azure-iot-device 包将文件从设备上传到 IoT 中心。
安装 SDK 包
运行以下命令,在开发计算机上安装 azure-iot-device 设备 SDK、azure-iot-device-mqtt 和 @azure/storage-blob 包:
npm install azure-iot-device azure-iot-device-mqtt @azure/storage-blob --save
azure-iot-device 包包含与 IoT 设备交互的对象。
按照此过程将文件从设备上传到 IoT 中心:
- 将设备连接到 IoT 中心
- 从 IoT 中心获取 Blob 共享访问签名 (SAS) 令牌
- 将文件上传到 Azure 存储
- 将文件上传状态通知发送到 IoT 中心
创建模块
使用已安装的包创建客户端、协议、错误和路径模块。
const Protocol = require('azure-iot-device-mqtt').Mqtt;
const errors = require('azure-iot-common').errors;
const path = require('path');
将设备连接到 IoT 中心
设备应用可以使用以下方法向 IoT 中心进行身份验证:
- X.509 证书
- 共享访问密钥
使用 X.509 证书进行身份验证
X.509 证书将附加到设备到 IoT 中心的连接传输。
若要配置一个使用 X.509 证书的设备到 IoT 中心的连接,请执行以下操作:
- 调用 fromConnectionString 以添加设备连接字符串和传输类型。 将
x509=true
添加到设备连接字符串,以指示已将证书添加到DeviceClientOptions
。 例如:HostName=xxxxx.azure-devices.net;DeviceId=Device-1;SharedAccessKey=xxxxxxxxxxxxx;x509=true
。 - 配置包含证书详细信息的 JSON 变量,并将其传递给 DeviceClientOptions。
- 调用 setOptions,将 X.509 证书和密钥(以及可选的密码)添加到客户端传输。
- 调用 open 以打开从设备到 IoT 中心的连接。
此示例显示 JSON 变量中的证书配置信息。 认证配置 options
将传递给 setOptions
,并使用 open
打开连接。
var options = {
cert: myX509Certificate,
key: myX509Key,
passphrase: passphrase,
http: {
receivePolicy: {
interval: 10
}
}
}
client.setOptions(options, callback);
client.open(connectCallback);
有关证书身份验证的详细信息,请参阅:
代码示例
有关设备 X.509 证书身份验证的工作示例,请参阅简单示例设备 X.509。
使用共享访问密钥进行身份验证
选择传输协议
Client
对象支持以下属性:
Amqp
Http
- 使用Http
时,Client
实例不会频繁地检查来自 IoT 中心的消息(至少每 25 分钟一次)。Mqtt
MqttWs
AmqpWs
在开发计算机上安装所需的传输协议。
例如,以下命令安装 Amqp
协议:
npm install azure-iot-device-amqp --save
有关 MQTT、AMQP 和 HTTPS 支持之间的差异的详细信息,请参阅云到设备通信指南和选择通信协议。
创建客户端对象
使用已安装的包创建 Client
对象。
例如:
const Client = require('azure-iot-device').Client;
创建协议对象
使用已安装的传输包创建 Protocol
对象。
此示例分配 AMQP 协议:
const Protocol = require('azure-iot-device-amqp').Amqp;
添加设备连接字符串和传输协议
调用 fromConnectionString 以提供设备连接参数:
- connStr - 设备连接字符串。
- transportCtor - 传输协议。
此示例使用 Amqp
传输协议:
const deviceConnectionString = "{IoT hub device connection string}"
const Protocol = require('azure-iot-device-mqtt').Amqp;
let client = Client.fromConnectionString(deviceConnectionString, Protocol);
打开到 IoT 中心的连接
使用 open 方法打开 IoT 设备与 IoT 中心之间的连接。
例如:
client.open(function(err) {
if (err) {
console.error('error connecting to hub: ' + err);
process.exit(1);
}
})
从 IoT 中心获取 SAS 令牌
使用 getBlobSharedAccessSignature 从 IoT 中心获取链接的存储帐户 SAS 令牌。
例如:
// make sure you set these environment variables prior to running the sample.
const localFilePath = process.env.PATH_TO_FILE;
const storageBlobName = path.basename(localFilePath);
const blobInfo = await client.getBlobSharedAccessSignature(storageBlobName);
if (!blobInfo) {
throw new errors.ArgumentError('Invalid upload parameters');
}
将文件上传到 IoT 中心
将文件从设备上传到 IoT 中心:
- 创建流管道
- 构造 Blob URL
- 创建 BlockBlobClient 以将文件上传到 Blob 存储
- 调用 uploadFile 将文件上传到 Blob 存储
- 调用 notifyBlobUploadStatus 以通知 IoT 中心上传是成功还是失败
例如:
// Open the pipeline
const pipeline = newPipeline(new AnonymousCredential(), {
retryOptions: { maxTries: 4 },
telemetry: { value: 'HighLevelSample V1.0.0' }, // Customized telemetry string
keepAliveOptions: { enable: false }
});
// Construct the blob URL
const { hostName, containerName, blobName, sasToken } = blobInfo;
const blobUrl = `https://${hostName}/${containerName}/${blobName}${sasToken}`;
// Create the BlockBlobClient for file upload to Blob Storage
const blobClient = new BlockBlobClient(blobUrl, pipeline);
// Setup blank status notification arguments to be filled in on success/failure
let isSuccess;
let statusCode;
let statusDescription;
const uploadStatus = await blobClient.uploadFile(localFilePath);
console.log('uploadStreamToBlockBlob success');
try {
const uploadStatus = await blobClient.uploadFile(localFilePath);
console.log('uploadStreamToBlockBlob success');
// Save successful status notification arguments
isSuccess = true;
statusCode = uploadStatus._response.status;
statusDescription = uploadStatus._response.bodyAsText;
// Notify IoT hub of upload to blob status (success)
console.log('notifyBlobUploadStatus success');
}
catch (err) {
isSuccess = false;
statusCode = err.code;
statusDescription = err.message;
console.log('notifyBlobUploadStatus failed');
console.log(err);
}
// Send file upload status notification to IoT hub
await client.notifyBlobUploadStatus(blobInfo.correlationId, isSuccess, statusCode, statusDescription);
将本地文件上传到 Blob 存储
你可以从计算机将本地文件上传到 Blob 存储
const deviceClient = Client.fromConnectionString(deviceConnectionString, Protocol);
uploadToBlob(localFilePath, deviceClient)
.catch((err) => {
console.log(err);
})
.finally(() => {
process.exit();
});
SDK 文件上传示例
此 SDK 包含一个上传到 Blob 高级示例。
创建后端应用程序
本部分介绍如何在后端应用程序中接收文件上传通知。
ServiceClient 类包含服务可用于接收文件上传通知的方法。
安装服务 SDK 包
运行以下命令,在开发计算机上安装“azure-iothub”:
npm install azure-iothub --save
连接到 IoT 中心
可使用以下方法将后端服务连接到 IoT 中心:
- 共享访问策略
- Microsoft Entra
重要
本文介绍使用共享访问签名连接到服务的步骤。 虽然可使用此身份验证方法进行测试和评估,但使用 Microsoft Entra ID 或托管标识对设备进行身份验证是一种更安全的方法。 有关详细信息,请参阅安全最佳做法和云安全。
使用共享访问策略进行连接
使用 fromConnectionString 连接到 IoT 中心。
若要从设备上传文件,你的服务需要具有“服务连接”权限。 默认情况下,每个 IoT 中心都使用名为“服务”的共享访问策略创建,该策略会授予此权限。
以 CreateFromConnectionString
的参数的形式,提供服务共享访问策略连接字符串。 有关共享访问策略的详细信息,请参阅使用共享访问签名控制对 IoT 中心的访问。
var Client = require('azure-iothub').Client;
var connectionString = '{IoT hub shared access policy connection string}';
var client = Client.fromConnectionString(connectionString);
使用 Microsoft Entra 进行连接
使用 Microsoft Entra 的后端应用必须在连接到 IoT 中心之前成功完成身份验证并获取安全令牌凭据。 此令牌将传递给 IoT 中心连接方法。 有关为 IoT 中心设置和使用 Microsoft Entra 的一般信息,请参阅使用 Microsoft Entra ID 控制对 IoT 中心的访问。
有关 Node.js SDK 身份验证的概述,请参阅:
配置 Microsoft Entra 应用
必须设置一个针对首选身份验证凭据进行配置的 Microsoft Entra 应用。 该应用包含由后端应用程序用来进行身份验证的参数,例如客户端机密。 可用的应用身份验证配置如下:
- 客户端机密
- 证书
- 联合标识凭据
根据正在执行的操作,Microsoft Entra 应用可能需要特定的角色权限。 例如,需要 IoT 中心孪生参与者角色才能启用对 IoT 中心设备和模块孪生的读写访问权限。 有关详细信息,请参阅使用 Azure RBAC 角色分配管理对 IoT 中心的访问。
有关设置 Microsoft Entra 应用的详细信息,请参阅快速入门:将应用程序注册到 Microsoft 标识平台。
使用 DefaultAzureCredential 进行身份验证
使用 Microsoft Entra 对后端应用程序进行身份验证的最简单方法是使用 DefaultAzureCredential,但建议在生产环境中使用其他方法,包括特定的 TokenCredential
或精简的 ChainedTokenCredential
。 为简单起见,本部分介绍如何使用 DefaultAzureCredential
和客户端机密进行身份验证。
有关使用 DefaultAzureCredential
的利弊的详细信息,请参阅适用于 JavaScript 的 Azure 标识客户端库中的凭据链
DefaultAzureCredential 支持不同的身份验证机制,并根据其执行环境确定相应的凭据类型。 它会尝试按顺序使用多种凭据类型,直到找到有效的凭据。
Microsoft Entra 需要此包:
npm install --save @azure/identity
在此示例中,Microsoft Entra 应用注册客户端机密、客户端 ID 和租户 ID 已添加到环境变量中。 DefaultAzureCredential
使用这些环境变量对应用程序进行身份验证。 成功 Microsoft Entra 身份验证的结果是传递给 IoT 中心连接方法的安全令牌凭据。
import { DefaultAzureCredential } from "@azure/identity";
// Azure SDK clients accept the credential as a parameter
const credential = new DefaultAzureCredential();
然后可以将生成的凭据令牌传递给 fromTokenCredential,以连接到任何接受 Microsoft Entra 凭据的 SDK 客户端的 IoT 中心:
fromTokenCredential
需要两个参数:
- Azure 服务 URL - Azure 服务 URL 应采用
{Your Entra domain URL}.azure-devices.net
格式(不包括https://
前缀)。 例如,MyAzureDomain.azure-devices.net
。 - Azure 凭据令牌
在此示例中,使用 DefaultAzureCredential
获取 Azure 凭据。 然后将 Azure 域 URL 和凭据提供给 Registry.fromTokenCredential
,以便与 IoT 中心创建连接。
const { DefaultAzureCredential } = require("@azure/identity");
let Registry = require('azure-iothub').Registry;
// Define the client secret values
clientSecretValue = 'xxxxxxxxxxxxxxx'
clientID = 'xxxxxxxxxxxxxx'
tenantID = 'xxxxxxxxxxxxx'
// Set environment variables
process.env['AZURE_CLIENT_SECRET'] = clientSecretValue;
process.env['AZURE_CLIENT_ID'] = clientID;
process.env['AZURE_TENANT_ID'] = tenantID;
// Acquire a credential object
const credential = new DefaultAzureCredential()
// Create an instance of the IoTHub registry
hostName = 'MyAzureDomain.azure-devices.net';
let registry = Registry.fromTokenCredential(hostName,credential);
代码示例
有关 Microsoft Entra 服务身份验证的有效示例,请参阅 Azure 标识示例。
创建文件上传通知回调接收器
若要创建文件上传通知回调接收器,请执行以下操作:
- 调用 getFileNotificationReceiver。 提供收到通知消息时调用的文件上传回调方法的名称。
- 在回调方法中处理文件上传通知。
此示例设置 receiveFileUploadNotification
通知回调接收方。 接收方解释文件上传状态信息,并将状态消息输出到控制台。
//Set up the receiveFileUploadNotification notification message callback receiver
serviceClient.getFileNotificationReceiver(function receiveFileUploadNotification(err, receiver){
if (err) {
console.error('error getting the file notification receiver: ' + err.toString());
} else {
receiver.on('message', function (msg) {
console.log('File upload from device:')
console.log(msg.getData().toString('utf-8'));
receiver.complete(msg, function (err) {
if (err) {
console.error('Could not finish the upload: ' + err.message);
} else {
console.log('Upload complete');
}
});
});
}
SDK 文件上传通知示例
SDK 包含一个文件上传示例。