基於華為物聯網IOT的應用開發 --- 基於.net 的SDK封裝

来源:https://www.cnblogs.com/wuhuacong/archive/2019/10/23/11726446.html
-Advertisement-
Play Games

最近,物聯網的概念比較熱門,一大批廠商搶著占領物聯網的高低,包括有華為物聯網、阿裡雲物聯網、騰訊物聯網、AWS物聯網等等,無法一一列舉,一般物聯網包含設備側開發、平臺側開發、應用側開發,三個部分構成了線上線下的完整連接,和我們常規的微信應用、釘釘應用等不同,物聯網的終端是由各種各樣的設備組合而成,這... ...


最近,物聯網的概念比較熱門,一大批廠商搶著占領物聯網的高低,包括有華為物聯網、阿裡雲物聯網、騰訊物聯網、AWS物聯網等等,無法一一列舉,一般物聯網包含設備側開發、平臺側開發、應用側開發,三個部分構成了線上線下的完整連接,和我們常規的微信應用、釘釘應用等不同,物聯網的終端是由各種各樣的設備組合而成,這些設備通過各種不同的協議(如CoAP,LWM2M、MQTT)連接到IOT的平臺,而且這些設備是低能耗的設備,可以實時的發送數據上來,也可以接受來自IOT平臺下發的各種操作指令。本篇隨筆主要介紹基於華為物聯網IOT的應用開發,實現對.net SDK的封裝,方便後期進行應用集成使用。

1、物聯網的相關介紹

物聯網其實有點類似我們以前做的一些行業設備的接入,不過它相對比較通用化一些,可以連接各種各樣的類型設備,而且更加安全、低能耗等,我們以前接入很多設備,可能需要走TCP/UDP協議,然後在後臺伺服器有一個對這些設備管理的一個Socket伺服器,不過和物聯網對比,這些都被徹底改造過了,以便適應更多的 應用場景,更簡化的開發,以及支持更強大的功能吧。

物聯網目前可以針對一些感測器採集一些特定的參數,如光感、溫度、濕度、壓力、電壓、電流等常規的信息,也可以擴展實現語音、圖像、視頻等方面的採集處理,如經典的智慧路燈應用場景。

下麵是其中的一個應用的架構設計,主要就是針對這些設備管理,物聯網還提供了很多完善的應用API介面,使得我們可以更加簡化對設備的管理(不用架設Socket服務),更加方便的通過API獲取相應的信息,節省更多的維護成本。

 

物聯網平臺支持海量設備連接上雲,設備與雲端可以實現穩定可靠地雙向通信。

  • 提供設備端SDK、驅動、軟體包等幫助不同設備、網關輕鬆接入物聯網雲。
  • 提供2G/ 3G /4G、NB-IoT、LoRa、WiFi等不同網路設備接入方案,解決企業異構網路設備接入管理痛點。
  • 提供MQTT、CoAP、HTTP/S等多種協議的設備端SDK,既滿足長連接的實時性需求,也滿足短連接的低功耗需求。
  • 開源多種平臺設備端代碼,提供跨平臺移植指導,賦能企業基於多種平臺做設備接入。

一般的物聯網平臺,都會包括產品管理、設備管理、設備組管理、規則引擎管理、消息推送和消息訂閱、任務管理、設備升級等等,不同的物聯網雲平臺有所不同。

 

物聯網的幾個相關的協議:

MQTT(Message Queue Telemetry Transport)

MQTT是一個物聯網傳輸協議,被設計用於輕量級的發佈/訂閱式消息傳輸,旨在為低帶寬和不穩定的網路環境中的物聯網設備提供可靠的網路服務。

MQTTS指MQTT+SSL/TLS,在MQTTS中使用SSL/TLS協議進行加密傳輸。

 

CoAP(Constrained Application Protocol)

受約束的應用協議(CoAP)是一種軟體協議,旨在使非常簡單的電子設備能夠在互聯網上進行互動式通信。

CoAPS指CoAP over DTLS,在CoAPS中使用DTLS協議進行加密傳輸。

 

LWM2M(lightweight Machine to Machine)

LWM2M是由OMA(Open Mobile Alliance)定義的物聯網協議,主要使用在資源受限(包括存儲、功耗等)的NB-IoT終端

 

2、應用側開發介面

應用側的開發介面一般雲平臺都會提供不同平臺的SDK,如阿裡雲開源提供Java SDK/C# SDK等;而華為則提供了Java、PHP等SDK,沒有包含.net 的SDK。

阿裡物聯網雲的應用側API介面包括:

 華為物聯網雲的應用側API介面包括:

 

 本篇主要介紹最基礎的物聯網SDK的包裝,以方便後續的應用開發集成。本篇隨筆也主要是基於華為應用側API的封裝,使用C#語言實現對.net SDK的全部封裝處理。

 針對上面的介面分類,我們定義不同的介面類來處理它們。

基本上所有API訪問都先需要通過鑒權介面獲取訪問的token,鑒權介面定義如下所示。

而且華為的API介面,需要使用X509證書處理的,我們可以通過在官網下載對應的X509證書進行集成測試API。

為了實現對API進行的.net SDK封裝,我們定義一些系統常見變數,方便在介面中使用。

 

 根據鑒權返回的結果,我們定義一個對應的實體類來存儲這些屬性信息,如下所示。

    /// <summary>
    /// 鑒權結果
    /// </summary>
    public class AuthenticationResult : BaseJsonResult
    {
        /// <summary>
        /// 申請許可權範圍,即accessToken所能訪問物聯網平臺資源的範圍,參數值固定為default。
        /// </summary>
        public string scope { get; set; }

        /// <summary>
        /// accessToken的類型,參數值固定為Bearer 。
        /// </summary>
        public string tokenType { get; set; }

        /// <summary>
        /// accessToken的有效時間,參數值固定為3600秒
        /// </summary>
        public int expiresIn { get; set; }

        /// <summary>
        /// 鑒權參數,訪問物聯網平臺API介面的憑證。
        /// </summary>
        public string accessToken { get; set; }

        /// <summary>
        /// 鑒權參數,有效時間為1個月,用於“刷新Token”介面。
        /// 當accessToken即將過期時,可通過“刷新Token”介面來獲取新的accessToken。
        /// </summary>
        public string refreshToken { get; set; }
    }

然後根據鑒權定義,我們實現對這個介面的封裝處理。

    /// <summary>
    /// IOT鑒權介面實現
    /// </summary>
    public class AuthenticationApi : IAuthenticationApi
    {
        /// <summary>
        /// 用戶鑒權
        /// 應用伺服器首次訪問物聯網平臺的開放API時,需調用此介面完成接入認證;
        /// 應用伺服器在物聯網平臺的認證過期後,需調用此介面重新進行認證,才能繼續訪問物聯網平臺的開放API。
        /// </summary>
        public AuthenticationResult Authentication()
        {
            string postData = string.Format("appId={0}&secret={1}", Constants.AppId, Constants.Secret);
            var url = Constants.AppBaseUrl + "/iocm/app/sec/v1.1.0/login";//名稱大小寫不能錯

            HttpHelper helper = new HttpHelper();
            helper.ContentType = "application/x-www-form-urlencoded";
            helper.ClientCertificates = new X509CertificateCollection() { new X509Certificate2(Constants.CertFilePath, Constants.CertPassword) };

            string content = helper.GetHtml(url, postData, true);
            var result = JsonConvert.DeserializeObject<AuthenticationResult>(content);
            return result;
        }

對於Token的刷新操作,封裝也是類似操作

        /// <summary>
        /// 刷新token。
        /// 應用伺服器通過鑒權介面獲取到的accessToken是有有效時間的,在accessToken快過期時,
        /// 應用伺服器通過調用此介面,獲取新的accessToken。
        /// </summary>
        /// <param name="refreshToken">
        /// 刷新token,用來獲取一個新的accessToken。refreshToken在調用鑒權介面或刷新token介面時獲得。
        /// </param>
        /// <returns></returns>
        public AuthenticationResult RefreshToken(string refreshToken)
        {
            string postData = new
            {
                appId = Constants.AppId,
                secret = Constants.Secret,
                refreshToken = refreshToken
            }.ToJson();
            var url = Constants.AppBaseUrl + "/iocm/app/sec/v1.1.0/refreshToken";//名稱大小寫不能錯

            var result = WeJsonHelper<AuthenticationResult>.ConvertJson(url, postData);
            return result;
        }

上面有些是為了方便操作,定義了一些公用類庫,以減少代碼的重覆。

一般除了鑒權外的所有的API,它們處理方式都類似的,都是以 application/json 格式進行交互,使用POST、PUT、GET、Delete操作方式實現對數據的處理。

而且它們都需要有固定的請求頭信息,我們以設備註冊為例進行介紹。

 

一般我們可以通過一個函數封裝,對介面的頭部請求信息進行設置,如下所示。

        /// <summary>
        /// 通用獲取頭部信息
        /// </summary>
        /// <param name="accessToken">介面訪問口令</param>
        /// <returns></returns>
        protected NameValueCollection GetHeader(string accessToken)
        {
            var header = new NameValueCollection();
            header.Add(Constants.HEADER_APP_KEY, Constants.AppId);
            header.Add(Constants.HEADER_APP_AUTH, string.Format("Bearer {0}", accessToken));
            return header;
        }

然後在定義請求的JSON和返回的JSON對應的實體類對象,封裝對應的API介面即可。

例如,我們註冊設備的介面封裝如下所示。

    /// <summary>
    /// 設備管理介面實現
    /// </summary>
    public class DeviceApi : BaseCommon, IDeviceApi
    {
        /// <summary>
        /// 註冊設備(驗證碼方式)。
        /// 在設備接入物聯網平臺前,應用伺服器需要調用此介面在物聯網平臺註冊設備,並設置設備的唯一標識(如IMEI)。
        /// 在設備接入物聯網平臺時攜帶設備唯一標識,完成設備的接入認證。
        /// </summary>
        /// <param name="accessToken"></param>
        /// <param name="info"></param>
        /// <returns></returns>
        public RegDeviceResult RegisterDevice(string accessToken, RegDeviceJson info)
        {
            var header = GetHeader(accessToken);

            string postData = info.ToJson();
            var url = Constants.AppBaseUrl + "/iocm/app/reg/v1.1.0/deviceCredentials";//名稱大小寫不能錯
            url += string.Format("?appId={0}", Constants.AppId);

            var result = WeJsonHelper<RegDeviceResult>.ConvertJson(url, postData, header);
            return result;
        }
......

這裡請求的信息是 RegDeviceJson , 返回信息的類是RegDeviceResult 。我們依照API定義,實現對應的處理即可。

為了方便處理,我們可以把這些對應設備的實體類定義在一個文件裡面,如DeviceJson.cs裡面,如下所示,這樣非常方便我們管理。

 

 其他業務範疇的Api也是如此封裝,不在一一贅述。

我們測試的時候,可以建立一個單獨的Winform項目進行介面功能的測試,也可以自己編寫單元測試代碼進行測試,根據自己熟練程度選擇吧。

例如鑒權介面測試代碼如下所示,我們可以看看輸出進行判斷是否正常工作。

        private void btnLogin_Click(object sender, EventArgs e)
        {
            var result = basicApi.Authentication();
            Console.WriteLine(result != null ? "accessToken:" + result.ToJson() : "獲取結果出錯");

            if (result != null)
            {
                var refreshResult = basicApi.RefreshToken(result.refreshToken);

                Console.WriteLine(refreshResult != null ? "accessToken:" + refreshResult.ToJson() : "獲取結果出錯");
                this.accessToken = refreshResult.accessToken;//記錄待用
            }
        }

設備註冊的功能測試如下所示。

        private void btnRegDevice_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(accessToken))
            {
                MessageUtil.ShowTips("請先鑒權獲取AccessToken");
                return;
            }

            var deviceApi = new DeviceApi();
            var regDeviceInfo = new RegDeviceJson()
            {
                endUserId = "64bf5869-b271-4007-8db8-fab185e19c10",
                nodeId = "64bf5869-b271-4007-8db8-fab185e19c10",
                psk = "12345678",
                timeout = 0,
                verifyCode = "",
                deviceInfo = new DeviceJson()
                {
                    deviceType = "Smoke",
                    manufacturerId = "49ac78c99f3e453598c155870efe8bfc",
                    manufacturerName = "iqidi",
                    //與manufacturerId、manufacturerName、deviceType、model和protocolType系列參數二選一
                    //productId = "5d9bf49b6a018f02d04cae28",
                    model = "1001",
                    name = "NBSimulator",
                    imsi = "fafafasfasf",
                    mac = "testetst",
                    isSecurity = true.ToString().ToUpper(),
                    protocolType = "LWM2M",
                }
            };

            var regResult = deviceApi.RegisterDevice(accessToken, regDeviceInfo);
            Console.WriteLine(regResult != null ? regResult.ToJson() : "no regResult");
        }

另外對於事件的通知,我們一般是在應用端被動的進行相應的處理,因此需要對它們的消息進行轉換和處理。

 

 針對以上的消息通知,我們需要定義對應的消息類型,然後進行判斷處理。

我們另起一個項目,然後定義對應給的事件接收處理,如下所示是一個統一的入口處理。

 

有了一個總入口,我們把對應通知的信息轉換為對應的實體後,就可以進行記錄或者響應的處理了。

在後面我們接著開發應用功能的時候,這些對應的介面API就可以集成整合在我們的系統中了。

 

 以上就是對於華為物聯網IOT平臺應用側的API封裝處理的思路, 供大家參考交流。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [TOC] GIL全局解釋鎖 1. GIL本質上是一個互斥鎖。 2. GIL是為了阻止同一個進程內多個進程同時執行(並行) 單個進程下的多個線程無法實現並行,但能實現併發 3. 這把鎖主要是因為Cpython的記憶體管理不是線程安全的 保證線程在執行任務時不會被垃圾回收機制回收 多線程的作用 1. 計 ...
  • 本節內容: 1、剖析Hello,World程式 1.1初始類(class)與名稱空間(namespace) 2、類庫的引用 2.1DLL的引用(黑盒引用) 2.2項目引用(白盒引用) 2.3建立自己的類庫項目 3、依賴關係 4、排除錯誤 1、剖析Hello,World程式 1.1、類(class)構 ...
  • 前言 當你在處理非同步消息時,每個單獨的消息處理程式都是一個單獨的handler,每個handler之間互不影響。這時如果一個消息依賴另一個消息的狀態呢? 這時業務邏輯怎麼處理? 借用我們上篇文章的業務場景,如果在Ship項目里需要發送一個ShipOrder Command。這個ShipOrder需要 ...
  • sqlsercer事務的使用總結,主要簡單減少sql事務的使用以及一些註意點。根據SQLSERVER實現原理,其實,SQLSERVER的每一條執行語句都是一個事務操作,也就是說每一個SQL語句要麼操作都成功,要麼操作都失敗:比如,更新語句,同時更新多個欄位,不會出現有的欄位更新成功,有的欄位更新失敗... ...
  • 本文摘自LTP.NET知識庫。 正則表達式的形式一般如下: 其中位於“/”定界符之間的部分就是將要在目標對象中進行匹配的模式。 用戶只要把希望查找匹配對象的模式內容放入“/”定界符之間即可。 為了能夠使用戶更加靈活的定製模式內容,正則表達式提供了專門的“ 元字元 ”。 所謂元字元就是指那些在正則表達 ...
  • 本人嘗試著利用C#語言來寫一個房貸計算器控制台程式。由於剛開始學,錯誤與失誤之處會很多。希望大家多多批評指正,我會持續改進。謝謝大家。 using System;using System.Collections.Generic;using System.Linq;using System.Text; ...
  • 問題 有一批數據,需要對每個元素進行相同的操作。該操作是計算密集型的,需要耗費一定的時間。 解決方案 常見的操作可以粗略分為 計算密集型操作 和 IO密集型操作。計算密集型操作主要是依賴於CPU計算,所以可以最大限度利用多核CPU的並行操作非常適合計算密集型操作。圖像操作是比較常見的計算密集型操作, ...
  • 我們在使用到WINFORM窗體工作中,要求RichTextBox 加入行號; 之前有看到大牛們寫的,但是太複雜繁多,而且有用雙TextBox進行聯動,非常不錯,今天我們嘗試RichTextBox +Panel相互聯動如下效果. 左側灰色為Panel,右側為RichTextBox 控制項 1:準備Pan ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...