天天看點

阿裡雲物聯網 .NET Core 用戶端 | CZGL.AliIoTClient:7. 服務調用

預先在裝置編寫好相應的代碼,這些代碼能夠處理一個或多個任務,即為

服務

,一個服務包含一個或多個任務。

CZGL.AliIoTClient 中,伺服器下發服務調用指令不需要設定,預設伺服器可以直接下發指令而不需要經過用戶端同意。

雖然用戶端能夠直接接收伺服器的服務調用指令,但是必須要設定相應的方法綁定到委托中,方能處理指令。

下面會舉例說明如何使用服務調用:

  1. 裝置定義一個服務,這個服務是定時爆炸。
  2. 當收到伺服器下發的爆炸指令和定時爆炸時間,就會開始任務
  3. 爆炸後,傳回爆炸結果
  4. 伺服器下發指令給裝置,讓它爆炸
  5. 伺服器不管裝置怎麼爆炸,也不等你爆炸
  6. 裝置爆炸完了,去告訴伺服器裝置以及完成爆炸

1)設定服務調用

打開阿裡雲物聯網控制台,點選自定義功能,按以下定義。

服務定義:

輸入參數:

.png "設定輸入參數")

輸出參數:

阿裡雲物聯網 .NET Core 用戶端 | CZGL.AliIoTClient:7. 服務調用

2)定義服務說明

定義的服務,有輸入參數、輸出參數,是指伺服器向裝置下發指令調用服務,這個服務需要的輸入參數、調用這個服務後傳回的參數。

這個是相對裝置來說的,伺服器調用裝置的服務,給裝置傳入資料(輸入參數),然後裝置處理完畢,傳回結果(輸出參數)。

裡面有異步、同步方法,使用異步方法,伺服器不需要等待裝置響應結果,可以直接傳回。

同步方法,伺服器必須等待響應結果,一直沒有獲得結果則會逾時報錯。

使用的基礎測試代碼如下(請替換 DeviceOptions 的值):

static AliIoTClientJson client;
        static void Main(string[] args)
        {
            // 建立用戶端
            client = new AliIoTClientJson(new DeviceOptions
            {
                ProductKey = "a1A6VVt72pD",
                DeviceName = "json",
                DeviceSecret = "7QrjTptQYCdepjbQvSoqkuygic2051zM",
                RegionId = "cn-shanghai"
            });

            client.OpenPropertyDownPost();
            // 設定要訂閱的Topic、運作接收内容的Topic
            string[] topics = new string[] { client.CombineHeadTopic("get") };
            // 使用預設事件
            client.UseDefaultEventHandler();
            // 連接配接伺服器
            client.ConnectIoT(topics, null, 60);
            Console.ReadKey();
        }           

運作控制台程式,打開阿裡雲物聯網控制台,線上調試,找到服務,選擇

機器自動爆炸

在輸入框輸入以下内容:

{
    "timee":10
}           

點選發送,再檢視控制台輸出。

{"method":"thing.service.bom","id":"670534570","params":{"timee":10},"version":"1.0.0"}           

根據定義和要求,實際上收到服務調用指令後,需要進行處理并且傳回響應結果。

3)編寫接收模型和響應模型

收到的消息是 Alink json ,你可以通過 CZGL.AliIoTClient 轉換成相應的對象。

同樣,也需要将相應的對象轉成 Alink json 上傳到伺服器中,作為響應。

編寫接收模型:

裡面隻有一個很簡單的參數 timee ,這個就是在控制台定義的 傳入參數。

public class Bom
        {
            public string method { get { return "thing.service.bom"; } set { } }
            public string id { get; set; }
            public string version { get { return "1.0.0"; } set { } }
            public Params @params { get; set; }
            public class Params
            {
                public int timee { get; set; }
            }
            public Bom()
            {
                @params = new Params();
            }
        }           

編寫響應模型:

public class ReBom
        {
            public string id { get; set; }
            public int code { get; set; }
            public Data data { get; set; }
            public class Data
            {
                public int isbom { get; set; }
            }
            public ReBom()
            {
                data = new Data();
            }
        }           

4)定義委托方法

CZGL.AliIoTClient 中,有個 PubServiceEventHandler 委托,當收到伺服器的服務調用指令時,這個委托就會觸發響應的事件。

是以,我們編寫一個處理指令的方法,另外自定義一個委托方法。

服務調用方法:

/// <summary>
        /// 服務調用方法
        /// </summary>
        /// <param name="timee"></param>
        /// <returns></returns>
        public static bool BomServer(int timee)
        {
            Console.WriteLine($"我将在 {timee} 秒後爆炸");
            /*
             * 其它代碼 *
             */
            // 傳回處理結果,已經爆炸
            return true;
        }           

編寫委托方法:

當收到服務調用指令時,應當如何處理。

/// <summary>
        /// 收到服務調用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void Service_Bom_EventHandler(object sender, MqttMsgPublishEventArgs e)
        {
            // handle message received
            string topic = e.Topic;
            string message = Encoding.ASCII.GetString(e.Message);
            if (topic.Contains("bom"))
            {
                // 将收到的服務調用資料轉為對象
                var model = client.Thing_Service_JsonToObject<Bom>(message);

                // 擷取裡面的timee參數,将這個參數傳入給方法進行處理
                var re = BomServer([email protected]);

                // 設定要傳回的資訊
                var reModel = new ReBom()
                {
                    code = 200,
                    id = model.id
                };
                reModel.data.isbom = 1;

                // 對伺服器做出響應,傳回處理結果
                client.Thing_Service_Identifier_Reply<ReBom>(reModel, "bom", false);
            }
        }           

如果你有多個服務,那麼在上面給出的示例方法

Service_Bom_EventHandler

中,加個判斷即可。

總之,這些是自定義的,靈活性很高,CZGL.AliIoTClient 負責将你的資料處理以及進行上傳下達,但是如何處理指令,需要你編寫相應的處理方法。

5)綁定到委托中

在連接配接伺服器前,綁定到委托中

client.PubServiceEventHandler += Service_Bom_EventHandler;
            // 連接配接伺服器
            client.ConnectIoT(topics, null, 60);           

就這麼一句代碼而已。

當然, CZGL.AliIoTClient 預設有一些方法,在收到伺服器消息時觸發,這些不會影響到你的委托方法。

如果你不需要,去除即可。

// 使用預設事件
            // client.UseDefaultEventHandler();

            client.PubServiceEventHandler += Service_Bom_EventHandler;
            // 連接配接伺服器
            client.ConnectIoT(topics, null, 60);           

至此,完整的代碼如下:

class Program
    {
        static AliIoTClientJson client;
        static void Main(string[] args)
        {
            // 建立用戶端
            client = new AliIoTClientJson(new DeviceOptions
            {
                ProductKey = "a1A6VVt72pD",
                DeviceName = "json",
                DeviceSecret = "7QrjTptQYCdepjbQvSoqkuygic2051zM",
                RegionId = "cn-shanghai"
            });

            client.OpenPropertyDownPost();
            // 設定要訂閱的Topic、運作接收内容的Topic
            string[] topics = new string[] { client.CombineHeadTopic("get") };
            // 使用預設事件
            client.UseDefaultEventHandler();

            client.PubServiceEventHandler += Service_Bom_EventHandler;
            // 連接配接伺服器
            client.ConnectIoT(topics, null, 60);
            Console.ReadKey();
        }

        /// <summary>
        /// 收到服務調用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void Service_Bom_EventHandler(object sender, MqttMsgPublishEventArgs e)
        {
            // handle message received
            string topic = e.Topic;
            string message = Encoding.ASCII.GetString(e.Message);
            if (topic.Contains("bom"))
            {
                // 将收到的服務調用資料轉為對象
                var model = client.Thing_Service_JsonToObject<Bom>(message);

                // 擷取裡面的timee參數,将這個參數傳入給方法進行處理
                var re = BomServer([email protected]);

                // 設定要傳回的資訊
                var reModel = new ReBom()
                {
                    code = 200,
                    id = model.id
                };
                reModel.data.isbom = 1;

                // 對伺服器做出響應,傳回處理結果
                client.Thing_Service_Identifier_Reply<ReBom>(reModel, "bom", false);
            }
        }

        public class Bom
        {
            public string method { get { return "thing.service.bom"; } set { } }
            public string id { get; set; }
            public string version { get { return "1.0.0"; } set { } }
            public Params @params { get; set; }
            public class Params
            {
                public int timee { get; set; }
            }
            public Bom()
            {
                @params = new Params();
            }
        }
        public class ReBom
        {
            public string id { get; set; }
            public int code { get; set; }
            public Data data { get; set; }
            public class Data
            {
                public int isbom { get; set; }
            }
            public ReBom()
            {
                data = new Data();
            }
        }
        /// <summary>
        /// 服務調用方法
        /// </summary>
        /// <param name="timee"></param>
        /// <returns></returns>
        public static bool BomServer(int timee)
        {
            Console.WriteLine($"我将在 {timee} 秒後爆炸");
            /*
             * 其它代碼 *
             */
            // 傳回處理結果,已經爆炸
            return true;
        }
    }           

5)伺服器下發服務調用指令

運作上面設定的程式,打開阿裡雲物聯網控制台,進入 線上調試。

選擇示範的産品、裝置,選擇上面定義的機器自動爆炸服務。

在文本框輸入以下内容

{
    "timee":10
}           

點選 發送指令 ,然後點一下 重新整理。

可以看到右側出現了 裝置上報資料、雲端下發資料

再到裝置中,在導航欄點選 服務調用,即可看到調用的服務、傳入參數、輸出參數等資訊。

6)後續說明

上傳響應時,響應的 id 必須與收到的指令 id 一緻。

繼續閱讀