Use o SDK para .NET para conectar um cliente AMQP ao Alibaba Cloud IoT Platform e receber mensagens de assinatura do lado do servidor.
Pré-requisitos
Obtenha um ID de grupo de consumidores e assine as mensagens de tópico necessárias.
Gerenciar grupos de consumidores AMQP: Use o grupo de consumidores padrão (DEFAULT_GROUP) no IoT Platform ou crie um novo grupo.
Configurar uma assinatura do lado do servidor AMQP: Assine as mensagens de tópico desejadas usando um grupo de consumidores.
Ambiente de desenvolvimento
A tabela a seguir lista os frameworks e as versões compatíveis.
|
Framework |
Versão compatível |
|
.NET Framework |
3,5, 4,0, 4,5 ou posterior |
|
.NET Micro Framework |
4,2 ou posterior |
|
.NET nanoFramework |
1,0 ou posterior |
|
.NET Compact Framework |
3,9 ou posterior |
|
.Net Core no Windows 10 e Ubuntu 14.04 |
1,0 ou posterior |
|
Mono |
4.2.1 ou posterior |
Baixe o SDK
Recomendamos a biblioteca AMQP.Net Lite. Para baixar a biblioteca e consultar as instruções, acesse AMQP.Net Lite.
Adicione a dependência
Adicione a seguinte dependência ao arquivo packages.config:
<packages>
<package id="AMQPNetLite" version="2.2.0" targetFramework="net47" />
</packages>
Código de exemplo
using System;
using System.Text;
using Amqp;
using Amqp.Sasl;
using Amqp.Framing;
using System.Threading;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Security.Cryptography;
namespace amqp
{
class MainClass
{
// The endpoint. For more information, see Connect an AMQP client to IoT Platform.
static string Host = "${YourHost}";
static int Port = 5671;
// Hardcoding the AccessKey ID and AccessKey Secret in your code poses security risks. We recommend using environment variables to store your credentials. This example demonstrates how to retrieve the AccessKey ID and AccessKey Secret from environment variables.
static string AccessKey = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID");
static string AccessSecret = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
static string consumerGroupId = "${YourConsumerGroupId}";
static string clientId = "${YourClientId}";
// The ID of the instance.
static string iotInstanceId = "${YourIotInstanceId}";
static int Count = 0;
static int IntervalTime = 10000;
static Address address;
public static void Main(string[] args)
{
long timestamp = GetCurrentMilliseconds();
string param = "authId=" + AccessKey + "×tamp=" + timestamp;
// For information about how to construct the userName parameter, see Connect an AMQP client to IoT Platform.
string userName = clientId + "|authMode=aksign,signMethod=hmacmd5,consumerGroupId=" + consumerGroupId
+ ",iotInstanceId=" + iotInstanceId + ",authId=" + AccessKey + ",timestamp=" + timestamp + "|";
// Calculate the signature. For information about how to construct the password, see Connect an AMQP client to IoT Platform.
string password = doSign(param, AccessSecret, "HmacMD5");
DoConnectAmqp(userName, password);
ManualResetEvent resetEvent = new ManualResetEvent(false);
resetEvent.WaitOne();
}
static void DoConnectAmqp(string userName, string password)
{
address = new Address(Host, Port, userName, password);
// Create a connection.
ConnectionFactory cf = new ConnectionFactory();
// Optional: Use a local TLS certificate.
//cf.SSL.ClientCertificates.Add(GetCert());
//cf.SSL.RemoteCertificateValidationCallback = ValidateServerCertificate;
cf.SASL.Profile = SaslProfile.External;
cf.AMQP.IdleTimeout = 120000;
// Customize the cf.AMQP.ContainerId and cf.AMQP.HostName parameters.
cf.AMQP.ContainerId = "client.1.2";
cf.AMQP.HostName = "contoso.com";
cf.AMQP.MaxFrameSize = 8 * 1024;
var connection = cf.CreateAsync(address).Result;
// Register a callback to handle connection closure.
connection.AddClosedCallback(ConnClosed);
// Receive messages.
DoReceive(connection);
}
static void DoReceive(Connection connection)
{
// Create a session.
var session = new Session(connection);
// Create a receiver link to receive messages.
var receiver = new ReceiverLink(session, "queueName", null);
receiver.Start(20, (link, message) =>
{
object messageId = message.ApplicationProperties["messageId"];
object topic = message.ApplicationProperties["topic"];
string body = Encoding.UTF8.GetString((Byte[])message.Body);
// Note: Avoid long-running tasks in this callback. If you need to perform business logic, run it in a separate thread. This prevents the consumer from being blocked, which can lead to message redelivery.
Console.WriteLine("receive message, topic=" + topic + ", messageId=" + messageId + ", body=" + body);
// Acknowledge the message.
link.Accept(message);
});
}
// If a connection error occurs, the client attempts to reconnect.
// This is a simple retry example. For production environments, consider implementing a more robust reconnection strategy, such as exponential backoff.
static void ConnClosed(IAmqpObject _, Error e)
{
Console.WriteLine("An error occurred: " + e);
if(Count < 3)
{
Count += 1;
Thread.Sleep(IntervalTime * Count);
}
else
{
Thread.Sleep(120000);
}
// Reconnect.
DoConnectAmqp(address.User, address.Password);
}
static X509Certificate GetCert()
{
string certPath = Environment.CurrentDirectory + "/root.crt";
X509Certificate crt = new X509Certificate(certPath);
return crt;
}
static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
static long GetCurrentMilliseconds()
{
DateTime dt1970 = new DateTime(1970, 1, 1);
DateTime current = DateTime.Now;
return (long)(current - dt1970).TotalMilliseconds;
}
// Signature method. Supported algorithms: hmacmd5, hmacsha1, and hmacsha256.
static string doSign(string param, string accessSecret, string signMethod)
{
//signMethod = HmacMD5
byte[] key = Encoding.UTF8.GetBytes(accessSecret);
byte[] signContent = Encoding.UTF8.GetBytes(param);
var hmac = new HMACMD5(key);
byte[] hashBytes = hmac.ComputeHash(signContent);
return Convert.ToBase64String(hashBytes);
}
}
}
Configure os parâmetros no código anterior conforme descrito na tabela a seguir. Para mais informações, consulte Conectar um cliente AMQP ao IoT Platform.
Especifique valores válidos para os parâmetros. Caso contrário, o cliente AMQP não conseguirá se conectar ao IoT Platform.
|
Parâmetro |
Descrição |
|
Host |
O endpoint de conexão AMQP. Para obter mais informações sobre o endpoint especificado na variável |
|
AccessKey |
Faça login no console do IoT Platform, passe o mouse sobre o ícone de perfil no canto superior direito e clique em AccessKey Management para obter o AccessKey ID e o AccessKey secret. Nota
Se você usar um usuário RAM, anexe a política AliyunIOTFullAccess a esse usuário para conceder permissões de gerenciamento de recursos do IoT Platform. Caso contrário, a conexão falhará. Para mais informações, consulte Acessar o IoT Platform como um usuário RAM. |
|
AccessSecret |
|
|
consumerGroupId |
O ID do grupo de consumidores na instância do IoT Platform. Faça login no console do IoT Platform. Na instância correspondente, acesse para visualizar o ID do seu grupo de consumidores. |
|
iotInstanceId |
O ID da instância. Encontre esse valor na guia Overview do console do IoT Platform.
|
|
clientId |
O ID do cliente. Defina este ID, que pode ter até 64 caracteres. Recomendamos usar um identificador exclusivo, como UUID, endereço MAC ou endereço IP do servidor onde o cliente AMQP está localizado. Após conectar e iniciar o cliente AMQP, faça login no console do IoT Platform. Na página da instância, clique em View ao lado do grupo de consumidores na guia Consumer Groups. A página Consumer Group Details exibirá este parâmetro para facilitar a identificação dos diferentes clientes. |
Resultados de exemplo
-
Sucesso: A saída abaixo indica conexão e recebimento de mensagens bem-sucedidos.
receive message, topic=/xxx/xxx/thing/event/property/post, messageId=xxx, body={"deviceType":"xxx","iotId":"xxx","requestId":"xxx","checkFailedData":{},"productKey":"xxx"} receive message, topic=/xxx/xxx/thing/event/property/post, messageId=xxx, body={"deviceType":"xxx","iotId":"xxx","requestId":"xxx","checkFailedData":{},"productKey":"xxx"} receive message, topic=/xxx/xxx/thing/event/property/post, messageId=xxx, body={"deviceType":"xxx","iotId":"xxx","requestId":"xxx","checkFailedData":{},"productKey":"xxx"}Parâmetro
Exemplo
Descrição
topic
//*/thing/event/property/post
O tópico para envio de propriedades do dispositivo.
messageId
2****7
O ID da mensagem.
body
{"deviceType":"CustomCategory","iotId":"4EwuVV","requestId":"161268","checkFailedData":{},"productKey":"g4***S","gmtCreate":1612682173249,"deviceName":"Esensor","items":{"temperature":{"value":-1,"time":1612682173247},"humidity":{"value":74,"time":1612682173247}}}
O corpo da mensagem.
-
Falha: A saída a seguir indica falha na conexão.
Thread xxx has exited with code 0 (0x0). Exception thrown: xxx (in xxx L) An unhandled exception of type 'Sys xxx n' occurred in m xxx 11 One or more errors occurred.
Referências
Para mais detalhes sobre códigos de erro relacionados a mensagens de assinatura do lado do servidor, consulte Códigos de erro relacionados a mensagens.