Windows C#环境,推荐的方案是使用 MQTTnet 这个高性能、成熟的.NET库。结合AWS官方的 .NET SDK或社区方案,可以很好地完成你的需求。
下面是具体的实施步骤和代码示例。
核心实施步骤
第一步:云端准备 (AWS IoT Core)
这一步与上一轮回答基本一致,你需要完成以下操作:
-
创建"事物" (Thing):在AWS IoT Core控制台中,为你的印花设备创建一个"事物"。
-
生成并下载凭证 :为这个"事物"生成并下载安全凭证,包括设备证书 (
.pem.crt)、私钥 (.private.pem.key)和根CA证书 (如AmazonRootCA1.pem)。 -
创建并附加策略 (Policy) :创建一个IoT策略,允许设备执行
iot:Connect、iot:Publish和iot:Subscribe操作,并将该策略附加到设备证书上。 -
获取终端节点 (Endpoint) :在AWS IoT Core控制台的"设置"页面,找到你的终端节点地址 (例如
xxxxxxxxxx-ats.iot.<region>.amazonaws.com)。
第二步:创建C#项目并安装NuGet包
在你的Windows 10/11开发环境(如Visual Studio)中,创建或打开你的C#项目,然后通过NuGet包管理器安装以下核心库:
-
MQTTnet:核心MQTT客户端库。 -
MQTTnet.Extensions.ManagedClient(可选):提供自动重连和消息队列管理等高级功能。 -
System.Security.Cryptography.Pkcs:用于处理证书。
在"程序包管理器控制台"中运行以下命令:
bash
Install-Package MQTTnet
Install-Package MQTTnet.Extensions.ManagedClient
注意 :你可能需要额外引入
Oocx.ReadX509CertificateFromPem等辅助库来简化从PEM格式文件加载证书的过程。
第三步:编写C#连接代码
以下是一个使用 MQTTnet 连接AWS IoT Core并发布设备状态的完整示例。核心步骤包括:加载证书、配置TLS、发起连接和发布消息。
cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
namespace MqttPrinterStatus
{
class Program
{
// 1. 定义AWS IoT Core的终端节点和端口
private const string AwsIotEndpoint = "xxxxxxxxxx-ats.iot.<region>.amazonaws.com";
private const int AwsIotPort = 8883; // MQTT over TLS端口
// 2. 定义证书路径(请替换为你的实际路径)
private const string CaCertPath = @"C:\certs\AmazonRootCA1.pem";
private const string DeviceCertPath = @"C:\certs\device-certificate.pem.crt";
private const string DevicePrivateKeyPath = @"C:\certs\device-private.pem.key";
static async Task Main(string[] args)
{
// 3. 加载证书
var caCert = new X509Certificate2(CaCertPath);
var deviceCert = LoadCertificateWithPrivateKey(DeviceCertPath, DevicePrivateKeyPath);
// 4. 创建MQTT客户端选项
var options = new ManagedMqttClientOptionsBuilder()
.WithClientOptions(new MqttClientOptionsBuilder()
.WithTcpServer(AwsIotEndpoint, AwsIotPort)
.WithTls(new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
Certificates = new List<X509Certificate> { caCert, deviceCert },
AllowUntrustedCertificates = false,
IgnoreCertificateChainErrors = false,
IgnoreCertificateRevocationErrors = false
})
.WithClientId("YourPrinterDeviceId") // 建议使用Thing名称
.WithCleanSession()
.Build())
.Build();
// 5. 创建并启动托管客户端(支持自动重连)
var mqttClient = new MqttFactory().CreateManagedMqttClient();
await mqttClient.StartAsync(options);
// 6. 订阅云端指令(可选)
await mqttClient.SubscribeAsync("printer/command");
// 7. 模拟发送设备状态
while (true)
{
// 构造一个JSON格式的状态消息
var statusMessage = $"{{\"deviceId\":\"Printer01\",\"status\":\"Online\",\"printerStatus\":\"Ready\",\"timestamp\":\"{DateTime.UtcNow:o}\"}}";
var message = new MqttApplicationMessageBuilder()
.WithTopic("device/status")
.WithPayload(Encoding.UTF8.GetBytes(statusMessage))
.WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)
.Build();
await mqttClient.PublishAsync(message);
Console.WriteLine($"已发送状态: {statusMessage}");
await Task.Delay(TimeSpan.FromSeconds(30)); // 每30秒发送一次
}
}
// 辅助方法:从PEM文件加载带有私钥的证书
private static X509Certificate2 LoadCertificateWithPrivateKey(string certPath, string keyPath)
{
// 这里需要结合第三方库如 Oocx.ReadX509CertificateFromPem 或使用 OpenSSL 转换
// 为简化,此处假设已有转换好的 .pfx 文件,或使用其他方法加载
// 实际生产环境建议使用更健壮的加载方式
var certPem = File.ReadAllText(certPath);
var keyPem = File.ReadAllText(keyPath);
// 可以使用 BouncyCastle 或参考以下方式:
// 示例:使用 Oocx.ReadX509CertificateFromPem 库
// var reader = new Oocx.ReadX509CertificateFromPem.CertificateFromPemReader();
// return reader.LoadCertificateWithPrivateKeyFromStrings(certPem, keyPem);
// 警告:下面的代码仅为演示,实际需要正确实现PEM到X509Certificate2的转换。
throw new NotImplementedException("请使用正确的PEM加载方式,例如结合BouncyCastle或Oocx库。");
}
}
}
第四步:测试与验证
-
编译运行:在Visual Studio中编译并运行你的C#程序。
-
查看控制台日志:确认程序成功连接并开始发送状态消息。
-
云端验证:
-
在AWS IoT Core控制台的"MQTT测试客户端"中,订阅
device/status主题,验证是否能收到设备发送的JSON状态数据。 -
在"MQTT测试客户端"中,向
printer/command主题发布消息,测试设备是否能接收到云端指令。
-
关键注意事项与最佳实践
-
证书转换是关键难点 :在C#中直接使用
.pem格式的证书和私钥较为复杂。你可以采用以下方式:-
使用
OpenSSL将.pem证书和私钥合并为.pfx格式,然后使用X509Certificate2直接加载。 -
在项目中集成
BouncyCastle或Oocx.ReadX509CertificateFromPem等库来处理PEM格式。
-
-
使用托管客户端 :建议使用
ManagedMqttClient,它能自动处理网络中断后的重连和消息队列,提升应用稳定性。 -
消息格式 :推荐使用结构化的 JSON 格式来发送设备状态,便于云端和其他服务解析和处理。
-
错误处理 :务必添加
try-catch块来捕获连接失败、发布失败等异常,并进行日志记录。 -
避免使用保留消息和遗嘱消息:根据社区反馈,AWS IoT Core 对这两种MQTT特性的支持可能存在问题,应避免使用。