All Products
Search
Document Center

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

Last Updated:Oct 22, 2023

This topic describes how to use the SDK for .NET to connect an Advanced Message Queuing Protocol (AMQP) client to Alibaba Cloud IoT Platform and receive messages from IoT Platform by using the server-side subscription feature.

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 for 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, see the "Connect an AMQP client to IoT Platform" topic. 
        static string Host = "${YourHost}";
        static int Port = 5671;
        // If you hard-code the AccessKey pair in the project code, the AccessKey pair may be disclosed if the project code is leaked. In this case, the resources within your account become insecure. The following sample code provides an example on how to obtain the AccessKey pair from environment variables. This example is for reference only.
        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}";
        // iotInstanceId: The ID of the IoT Platform 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, 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 construct the password, 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 reconnect 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 description in the following table. For more information about other parameters, 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

Description

Host

The endpoint that the AMQP client uses to connect to IoT Platform.

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, move the pointer over the profile picture in the upper-right corner, and then click AccessKey Management to obtain the AccessKey ID and AccessKey secret.

Note

If you use a Resource Access Management (RAM) user, you must attach the AliyunIOTFullAccess policy to the RAM user. This policy allows the RAM user to manage IoT Platform resources. Otherwise, the connection to IoT Platform fails. For more information, see Access IoT Platform as a RAM user.

AccessSecret

consumerGroupId

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

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 manage. In the left-side navigation pane, choose Message Forwarding > Server-side Subscription. The ID of the consumer group is displayed on the Consumer Groups tab.

iotInstanceId

The ID of the IoT Platform instance. You can view the instance ID on the Overview tab in the IoT Platform console.

  • If an instance ID is displayed, you must 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 ID of the client. You must specify a custom ID. The ID must be 1 to 64 characters in length. We recommend that you use a unique identifier as the client ID, such as the UUID, MAC address, or IP address of the server on which the client runs.

After the AMQP client is connected to IoT Platform and started, perform the following steps to view the details of the client: Log on to the IoT Platform console and click the card of the instance that you want to manage. In the left-side navigation pane, choose Message Forwarding > Server-side Subscription. On the Consumer Groups tab, 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 Status tab. You can use client IDs to identify clients with ease.

Sample results

  • If information similar to the following output is displayed, the AMQP client is connected to IoT Platform and can receive messages.成功

    Parameter

    Example

    Description

    topic

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

    The topic that is used to submit device properties.

    messageId

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

    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 information similar to the following output is displayed, the AMQP client fails to connect to IoT Platform.失败

References

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