預先在裝置編寫好相應的代碼,這些代碼能夠處理一個或多個任務,即為 服務
,一個服務包含一個或多個任務。
CZGL.AliIoTClient 中,伺服器下發服務調用指令不需要設定,預設伺服器可以直接下發指令而不需要經過用戶端同意。
雖然用戶端能夠直接接收伺服器的服務調用指令,但是必須要設定相應的方法綁定到委托中,方能處理指令。
下面會舉例說明如何使用服務調用:
- 裝置定義一個服務,這個服務是定時爆炸。
- 當收到伺服器下發的爆炸指令和定時爆炸時間,就會開始任務
- 爆炸後,傳回爆炸結果
- 伺服器下發指令給裝置,讓它爆炸
- 伺服器不管裝置怎麼爆炸,也不等你爆炸
- 裝置爆炸完了,去告訴伺服器裝置以及完成爆炸
1)設定服務調用
打開阿裡雲物聯網控制台,點選自定義功能,按以下定義。
服務定義:
輸入參數:
.png "設定輸入參數")
輸出參數:

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 一緻。