Connect a client to IoT Platform by using the SDK for .NET

更新时间:
复制 MD 格式

Use the .NET SDK to connect an AMQP client to Alibaba Cloud IoT Platform and receive server-side subscription messages.

Prerequisites

You have obtained a consumer group ID and subscribed to the required topic messages.

Development environment

The following table lists the supported frameworks and versions.

Framework

Supported version

.NET Framework

3.5, 4.0, 4.5, or later

.NET Micro Framework

4.2 or later

.NET nanoFramework

1.0 or later

.NET Compact Framework

3.9 or later

.Net Core on Windows 10 and Ubuntu 14.04

1.0 or later

Mono

4.2.1 or later

Download the SDK

We recommend the AMQP.Net Lite library. To download the library and view its instructions, visit AMQP.Net Lite.

Add the dependency

Add the following dependency to the packages.config file:

<packages>
  <package id="AMQPNetLite" version="2.2.0" targetFramework="net47" />
</packages>

Sample code

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 + "&timestamp=" + 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 the parameters in the preceding code as described in the following table. For more information, see Connect an AMQP client to IoT Platform.

Important

Specify valid parameter values. Otherwise, the AMQP client fails to connect to IoT Platform.

Parameter

Description

Host

The AMQP connection endpoint.

For more information about the endpoint that you can specify for the ${YourHost} variable, see Manage the endpoint of an instance.

AccessKey

Log on to the IoT Platform console, hover over the profile icon in the upper-right corner, and then click AccessKey Management to obtain the AccessKey ID and AccessKey secret.

Note

If you use a RAM user, you must attach the AliyunIOTFullAccess policy to the RAM user to grant permissions for managing IoT Platform resources. Otherwise, the connection fails. For more information, see Access IoT Platform as a RAM user.

AccessSecret

consumerGroupId

The ID of the consumer group in the IoT Platform instance.

Log on to the IoT Platform console. In the corresponding instance, go to Message Forwarding > Server-side Subscription > Consumer Group List to view your consumer group ID.

iotInstanceId

The instance ID. You can find this value on the Overview tab in the IoT Platform console.

  • If an instance ID is displayed, set this parameter to the instance ID.

  • If the Overview tab is not displayed or your instance does not have an ID, leave this parameter empty in the format of iotInstanceId = "".

clientId

The client ID. You must define this ID. The ID can be up to 64 characters in length. We recommend that you use a unique identifier, such as the UUID, MAC address, or IP address of the server where your AMQP client is located.

After the AMQP client is connected and starts, log on to the IoT Platform console. On the Consumer Groups tab of the Message Forwarding > > > Server-side Subscription page for the instance, click View next to the consumer group. The Consumer Group Details page displays this parameter. This helps you identify different clients.

Sample results

  • Success: The following output indicates a successful connection and message receipt.

    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"}

    Parameter

    Example

    Description

    topic

    /***********/******/thing/event/property/post

    The topic for submitting device properties.

    messageId

    2**************7

    The message ID.

    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}}}

    The message body.

  • Failure: The following output indicates a failed connection.

    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.

References

For more information about error codes for server-side subscription messages, see Message-related error codes.