This topic describes how to use the AMQP SDK for .NET to connect a client to Alibaba Cloud IoT Platform and receive messages from IoT Platform.

Prerequisites

The ID of the consumer group that has subscribed to the messages of a topic is obtained.

Development environment

The following table describes the requirements on the development environment.

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 that you use 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 about the endpoint, see the "Connect an AMQP client to IoT Platform" topic. 
        static string Host = "${YourHost}";
        static int Port = 5671;
        static string AccessKey = "${YourAccessKey}";
        static string AccessSecret = "${YourAccessSecret}";
        static string consumerGroupId = "${YourConsumerGroupId}";
        static string clientId = "${YourClientId}";
        // iotInstanceId: 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;
            // The structure of the userName parameter. For more information about this parameter, see the "Connect an AMQP client to IoT Platform" topic. 
            string userName = clientId + "|authMode=aksign,signMethod=hmacmd5,consumerGroupId=" + consumerGroupId
               + ",iotInstanceId=" + iotInstanceId + ",authId=" + AccessKey + ",timestamp=" + timestamp + "|";
            // Calculate a signature. For more information about how to specify the password parameter, see the "Connect an AMQP client to IoT Platform" topic. 
            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();
            // Use a local TLS certificate if required. 
            //cf.SSL.ClientCertificates.Add(GetCert());
            //cf.SSL.RemoteCertificateValidationCallback = ValidateServerCertificate;
            cf.SASL.Profile = SaslProfile.External;
            cf.AMQP.IdleTimeout = 120000;
            // Configure 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;

            // The connection exception feature is disabled. 
            connection.AddClosedCallback(ConnClosed);

            // Receive messages. 
            DoReceive(connection);
        }

        static void DoReceive(Connection connection)
        {
            // Create a session. 
            var session = new Session(connection);

            // Create a receiver link and 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: Do not implement time-consuming logic. If you need to specify the business logic, use a new thread. Otherwise, message consumption may be blocked. Messages may be resent due to the latency of consumption. 
                Console.WriteLine("receive message, topic=" + topic + ", messageId=" + messageId + ", body=" + body);

                // Send an ACK message. 
                link.Accept(message);
            });


        }

        // If an exception occurs, the client attempts to re-connect to IoT Platform. 
        // You can use an exponential backoff algorithm to improve the exception handling mechanism and the reconnection policy. 
        static void ConnClosed(IAmqpObject _, Error e)
        {
            Console.WriteLine("ocurr error: " + e);
            if(Count < 3)
            {
                Count += 1;
                Thread.Sleep(IntervalTime * Count);
            }
            else
            {
                Thread.Sleep(120000);
            }

            // Re-establish the connection. 
            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;
        }

        // The signature algorithm. Valid values: 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);
        }
    }
}

You can configure the parameters in the preceding code based on the parameter descriptions in the following table. For more information about parameter descriptions, see Connect an AMQP client to IoT Platform.

Important Make sure that you specify valid parameter values. Otherwise, the AMQP client fails to connect to IoT Platform.
Parameter Example Description
Host 198426864******.iot-amqp.cn-shanghai.aliyuncs.com The AMQP endpoint.

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

AccessKey LTAI4GFGQvKuqHJhFa****** Log on to the IoT Platform console, move the pointer over the profile picture, 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 permission policy to the RAM user. This policy allows the RAM user to manage IoT Platform resources. Otherwise, the connection with IoT Platform fails. For more information about how to authorize a RAM user, see RAM user access.
AccessSecret iMS8ZhCDdfJbCMeA005sieKe******
consumerGroupId VWhGZ2QnP7kxWpeSSjt****** The ID of the consumer group.

To view the ID of the consumer group, perform the following steps: Log on to the IoT Platform console and click the card of the instance that you want to manange. Choose Rules Engine > Server-side Subscription > Consumer Groups. The ID is displayed on the Consumer Groups tab.

iotInstanceId "" The ID of the instance. You can view the ID of the instance on the Overview page in the IoT Platform console.
  • If you have an ID value, you must specify the ID for this parameter.
  • If no Overview or ID is generated for your instance, specify an empty string (iotInstanceId = "") for the parameter.
clientId 12345 The ID of the client. We recommend that you use a unique identifier, such as the UUID, MAC address, or IP address of the client. The client ID must be 1 to 64 characters in length.

Log on to the IoT Platform console and click the card of the instance that you want to manage. Choose Rules Engine > Server-side Subscription > Consumer Groups. Find the consumer group that you want to manage and click View in the Actions column. The ID of each client is displayed on the Consumer Group Details page. You can use client IDs to efficiently identify clients.

Sample results

  • If the displayed output is similar to the following log information, the AMQP client is connected to IoT Platform and can receive messages. Successful
    Parameter Example Description
    topic /***********/******/thing/event/property/post The topic that is used to submit device properties.
    messageId 1324198300680719360 The ID of the message.
    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 content of the message.
  • If the displayed output is similar to the following log information, the AMQP client fails to connect to IoT Platform. Failed

References

For more information about the error codes that are related to server-side subscription, see Error codes that are related to messages.