版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 Azure IoT 物聯(lián)網(wǎng)解決方案套件介紹微軟中國MSDN 微信號 cnmsdn功能介紹 微軟中國MSDN開發(fā)社區(qū)官方微信。物聯(lián)網(wǎng) (IoT) 解決方案包括遠(yuǎn)程遙測設(shè)備、Web 門戶、云存儲和實(shí)時(shí)處理功能。結(jié)構(gòu)如此復(fù)雜,你就更不愿意開始進(jìn)行 IoT 開發(fā)了。為了簡化工作,Microsoft Azure IoT 套件提供了以下兩個(gè)預(yù)配置解決方案:遠(yuǎn)程監(jiān)視和預(yù)測性維護(hù)。本文將介紹如何創(chuàng)建遠(yuǎn)程監(jiān)視解決方案,從而收集和分析 Windows 10 IoT 核心版控制的遠(yuǎn)程 IoT 設(shè)備中的數(shù)據(jù)。此 Raspberry Pi 設(shè)備將通過 USB 攝像頭采集圖像。隨后,圖像亮度會在 IoT 設(shè)備上進(jìn)行計(jì)算
2、,然后流式傳輸?shù)皆浦校⒃谠浦羞M(jìn)行存儲、處理和顯示(見圖 1)。此外,最終用戶不僅可以查看通過遠(yuǎn)程設(shè)備采集的信息,還能遠(yuǎn)程控制相應(yīng)設(shè)備。有關(guān)輔助此論述的完整源代碼,請?jiān)L問/magazine/0617magcode圖 1:Azure IoT 套件預(yù)配置解決方案門戶,以及用于采集并處理視頻流的遠(yuǎn)程通用 Windows 平臺應(yīng)用遠(yuǎn)程設(shè)備Frank LaVigne (/magazine/mt694090) 和 Bruno Sonnino (/magazine/mt808503) 已在本雜志中介紹過在安裝了 Windows 10 IoT 核心版的 Raspberry Pi 上進(jìn)行編程的基礎(chǔ)知識。LaVi
3、gne 和 Sonnino 介紹了如何設(shè)置開發(fā)環(huán)境和 IoT 開發(fā)板、如何在瀏覽器中使用設(shè)備門戶配置 IoT 單元,以及如何使用 Windows 10 IoT 核心版控制 GPIO 端口。此外,LaVigne 還在他的文章中提到,可以使用 IoT 對遠(yuǎn)程攝像頭進(jìn)行編程和控制。在本文中,我擴(kuò)展了這一想法,并明確介紹了如何將 Raspberry Pi 變成這樣的設(shè)備。為此,我使用空白應(yīng)用(通用 Windows)Visual C# 項(xiàng)目模板創(chuàng)建了 RemoteCamera 通用 Windows 平臺 (UWP) 應(yīng)用,然后將目標(biāo)和最低 API 版本設(shè)置為 Windows 10 周年版本(10.0;生
4、成號 14393)。我使用此 API 版本是為了能夠綁定到方法,從而直接將視圖模型的方法與可視控件觸發(fā)的事件相關(guān)聯(lián):接下來,我聲明了 UI,如圖 1所示。有兩個(gè)選項(xiàng)卡: “攝像頭捕捉”和“云”。第一個(gè)選項(xiàng)卡中的控件可用于啟動(dòng)或停止攝像頭預(yù)覽、顯示視頻流并呈現(xiàn)圖像亮度(標(biāo)簽和進(jìn)度欄)。第二個(gè)選項(xiàng)卡中有兩個(gè)按鈕,分別用于將設(shè)備連入云中,以及在 IoT 門戶中注冊設(shè)備?!霸啤边x項(xiàng)卡還包含一個(gè)復(fù)選框,用于啟用流式傳輸遙測數(shù)據(jù)。與 UI 相關(guān)聯(lián)的大部分邏輯是在 RemoteCameraViewModel 類(見 RemoteCamera 項(xiàng)目的 ViewModels 子文件夾)中實(shí)現(xiàn)。除了實(shí)現(xiàn)一些與 U
5、I 綁定的屬性之外,此類還負(fù)責(zé)處理視頻采集、圖像處理和云交互。這些子功能分別是在以下各個(gè)類中實(shí)現(xiàn): CameraCapture、ImageProcessor 和 CloudHelper。我很快將會介紹 CameraCapture 和 ImageProcessor,而 CloudHelper 及相關(guān)幫助程序類則稍后將在 Azure IoT 預(yù)配置解決方案上下文中進(jìn)行介紹。相機(jī)捕捉攝像頭捕捉(見 Helpers 文件夾下的 CameraCapture.cs)是在以下兩個(gè)元素的基礎(chǔ)之上生成: Windows.Media.Capture.MediaCapture class 和 Windows.UI.
6、Xaml.Controls.CaptureElement。前者用于采集視頻,而后者則用于顯示采集的視頻流。由于使用攝像頭采集視頻,因此必須在 Package.appxmanifest 中聲明相應(yīng)的設(shè)備功能。若要初始化 MediaCapture 類,請調(diào)用 InitializeAsync 方法。最終,可以向此方法傳遞 MediaCaptureInitializationSettings 類的實(shí)例,從而指定捕捉選項(xiàng)??梢赃x擇是流式傳輸視頻還是音頻,并選擇捕捉硬件。在本文中,我僅通過默認(rèn)攝像頭采集視頻(見圖 2)。圖 2:攝像頭捕捉初始化public MediaCapture get; privat
7、e set; = new MediaCapture();public bool IsInitialized get; private set; = false;public async Task Initialize(CaptureElement captureElement) if (!IsInitialized) var settings = new MediaCaptureInitializationSettings() StreamingCaptureMode = StreamingCaptureMode.Video ; try await MediaCapture.Initializ
8、eAsync(settings); GetVideoProperties(); captureElement.Source = MediaCapture; IsInitialized = true; catch (Exception ex) Debug.WriteLine(ex.Message); IsInitialized = false; 接下來,使用 CaptureElement 類實(shí)例的 Source 屬性,將此對象與 MediaCapture 控件相關(guān)聯(lián),以顯示視頻流。我還調(diào)用了幫助程序方法 GetVideoProperties,用于讀取并存儲視頻幀的大小。稍后會使用此信息來獲取預(yù)覽
9、幀以供處理。最后,為了能夠真正啟動(dòng)和停止視頻采集,我調(diào)用了 MediaCapture 類的 StartPreviewAsync 和 StopPreviewAsync。在 CameraCapture 中,我使用其他邏輯包裝了這些方法,同時(shí)驗(yàn)證了初始化和預(yù)覽狀態(tài):public async Task Start() if (IsInitialized) if (!IsPreviewActive) await MediaCapture.StartPreviewAsync(); IsPreviewActive = true; 運(yùn)行應(yīng)用時(shí),可以按“開始預(yù)覽”按鈕來配置攝像頭采集,之后不久就可以看到攝像頭圖
10、像。請注意,由于 RemoteCamera 應(yīng)用是通用應(yīng)用,因此無需進(jìn)行任何更改,即可部署到開發(fā) PC、智能手機(jī)、平板電腦或 Raspberry Pi。如果使用 Windows 10 PC 測試 RemoteCamera 應(yīng)用,需要確保應(yīng)用可使用攝像頭。可以使用“設(shè)置”應(yīng)用(“隱私”/“攝像頭”)來配置此設(shè)置。為了使用 Raspberry Pi 測試此應(yīng)用,我使用了預(yù)算較低的 Microsoft Life Cam HD-3000。由于這是一個(gè) USB 攝像頭,因此,當(dāng)我將它連到四個(gè) Raspberry Pi USB 端口之一后,Windows 10 IoT 核心版可以自動(dòng)檢測到攝像頭。有關(guān)與
11、Windows 10 IoT 核心版兼容的攝像頭的完整列表,請?jiān)L問bit.ly/2p1ZHGD。將攝像頭與 Rasbperry Pi 相連后,它顯示在“設(shè)備門戶”的“設(shè)備”選項(xiàng)卡下。圖像處理器ImageProcessor 類在后臺計(jì)算當(dāng)前幀的亮度。為了執(zhí)行后臺操作,我使用基于任務(wù)的異步模式創(chuàng)建了線程,如圖 3所示。圖 3:在后臺計(jì)算亮度public event EventHandler ProcessingDone;private void InitializeProcessingTask() processingCancellationTokenSource = new Cancellati
12、onTokenSource(); processingTask = new Task(async () = while (!processingCancellationTokenSource.IsCancellationRequested) if (IsActive) var brightness = await GetBrightness(); ProcessingDone(this, new ImageProcessorEventArgs(brightness); Task.Delay(delay).Wait(); , processingCancellationTokenSource.T
13、oken);在 while 循環(huán)中,我確定了圖像亮度,然后將此值傳遞給 ProcessingDone 事件的偵聽器。系統(tǒng)向此事件饋送 ImageProcessorEventArgs 類的實(shí)例,其中只有一個(gè)公共屬性 Brightness。在收到取消信號前,處理任務(wù)會一直運(yùn)行。圖像處理的關(guān)鍵元素是 GetBrightness 方法,如圖 4所示。圖 4:GetBrightness 方法private async Task GetBrightness() var brightness = new byte(); if (cameraCapture.IsPreviewActive) / Get cur
14、rent preview bitmap var previewBitmap = await cameraCapture.GetPreviewBitmap(); / Get underlying pixel data var pixelBuffer = GetPixelBuffer(previewBitmap); / Process buffer to determine mean gray value (brightness) brightness = CalculateMeanGrayValue(pixelBuffer); return brightness;我使用 CameraCaptur
15、e 類實(shí)例的 GetPreviewBitmap 來獲取預(yù)覽幀。在內(nèi)部,GetPreviewBitmap 使用 MediaCapture 類的 GetPreviewFrameAsync。GetPreviewFrameAsync 有兩個(gè)版本。第一個(gè)版本是無參數(shù)方法,返回的是 VideoFrame 類的實(shí)例。在這種情況下,可以通過讀取 Direct3DSurface 屬性來獲取實(shí)際的像素?cái)?shù)據(jù)。第二個(gè)版本接受 VideoFrame 類的實(shí)例,并將像素?cái)?shù)據(jù)復(fù)制到其 SoftwareBitmap 屬性中。在本文中,我使用第二個(gè)選項(xiàng)(見 CameraCapture 類的 GetPreviewBitmap 方
16、法),然后通過 SoftwareBitmap 類實(shí)例的 CopyToBuffer 方法訪問像素?cái)?shù)據(jù)(如圖 5所示)。圖 5:訪問像素?cái)?shù)據(jù)private byte GetPixelBuffer(SoftwareBitmap softwareBitmap) / Ensure bitmap pixel format is Bgra8 if (softwareBitmap.BitmapPixelFormat != CameraCapture.BitmapPixelFormat) SoftwareBitmap.Convert(softwareBitmap, CameraCapture.BitmapPix
17、elFormat); / Lock underlying bitmap buffer var bitmapBuffer = softwareBitmap.LockBuffer(BitmapBufferAccessMode.Read); / Use plane description to determine bitmap height / and stride (the actual buffer width) var planeDescription = bitmapBuffer.GetPlaneDescription(0); var pixelBuffer = new byteplaneD
18、escription.Height * planeDescription.Stride; / Copy pixel data to a buffer softwareBitmap.CopyToBuffer(pixelBuffer.AsBuffer(); return pixelBuffer;首先,我將確認(rèn)像素格式是否為 BGRA8。此像素格式表示圖像使用四個(gè) 8 位通道:三個(gè)通道分別用于表示藍(lán)色、綠色和紅色,另外一個(gè)通道用于表示 alpha 或透明度。如果輸入位圖采用其他像素格式,我會執(zhí)行相應(yīng)的轉(zhuǎn)換。接下來,我將把像素?cái)?shù)據(jù)復(fù)制到字節(jié)數(shù)組中,其大小由圖像高度與圖像步幅的乘積決定 (bit.ly/
19、2om8Ny9)。我從 BitmapPlaneDescription 實(shí)例中讀取這兩個(gè)值,此實(shí)例是通過 SoftwareBitmap.LockBuffer 方法返回的 BitmapBuffer 對象獲取而來。鑒于字節(jié)數(shù)組包含像素?cái)?shù)據(jù),只需計(jì)算所有像素的平均值即可。因此,我循環(huán)訪問了像素緩存(見圖 6)。圖 6:計(jì)算像素的平均值private byte CalculateMeanGrayValue(byte pixelBuffer) / Loop index increases by four since / there are four channels (blue, green, red a
20、nd alpha). / Alpha is ignored for brightness calculation const int step = 4; double mean = 0.0; for (uint i = 0; i DisplayBrightness(brightness); ); 預(yù)配遠(yuǎn)程監(jiān)視解決方案若要預(yù)配解決方案,可以使用專用門戶 ()。登錄并選擇 Azure 訂閱后,便會重定向到一個(gè)頁面,可以在其中按“創(chuàng)建新的解決方案”矩形框。這會打開一個(gè)網(wǎng)站,可以在其中選擇兩個(gè)預(yù)配置解決方案之一:預(yù)測性維護(hù)或遠(yuǎn)程監(jiān)視(見圖 8)。選擇解決方案后,將會看到另一個(gè)窗體,可以在其中設(shè)置 Az
21、ure 資源的解決方案名稱和區(qū)域。在本文中,我將解決方案名稱和區(qū)域分別設(shè)置為“RemoteCameraMonitoring”和“美國西部”。圖 8:Azure IoT 套件預(yù)配置解決方案(上)和遠(yuǎn)程監(jiān)視解決方案配置(下)預(yù)配遠(yuǎn)程監(jiān)視解決方案時(shí),Azure IoT 套件門戶會創(chuàng)建以下多個(gè) Azure 資源: IoT 中心、流分析作業(yè)、存儲和 App Service。IoT 中心可實(shí)現(xiàn)云和遠(yuǎn)程設(shè)備之間的雙向通信。流分析作業(yè)會轉(zhuǎn)換遠(yuǎn)程設(shè)備流式傳輸?shù)臄?shù)據(jù),通常是篩選掉不必要的數(shù)據(jù)。篩選后的數(shù)據(jù)會進(jìn)行存儲或定向,以供將來分析時(shí)使用。最后,App Service 用于托管 Web 門戶。也可以通過命令行完
22、成解決方案預(yù)配。為此,可以從bit.ly/2osI4RW克隆或下載解決方案源代碼,然后按照bit.ly/2p7MPPc中的說明操作。也可以視需要在本地部署解決方案,如bit.ly/2nEePNi所述。在這種情況下,不會創(chuàng)建 Azure App Service,因?yàn)榻鉀Q方案門戶是在本地計(jì)算機(jī)上運(yùn)行。若要進(jìn)行開發(fā)和調(diào)試或修改預(yù)配置解決方案,就會發(fā)現(xiàn)此類方法特別有用。完成預(yù)配后,可以啟動(dòng)解決方案,它的門戶顯示在默認(rèn)瀏覽器中(再次見圖 1)。此門戶包含多個(gè)選項(xiàng)卡。在本文中,我將僅關(guān)注其中兩個(gè)選項(xiàng)卡,即“儀表板”和“設(shè)備”?!皟x表板”顯示遠(yuǎn)程設(shè)備及其流式傳輸?shù)倪b測數(shù)據(jù)的映射?!霸O(shè)備”選項(xiàng)卡顯示遠(yuǎn)程設(shè)備列
23、表,包括設(shè)備的狀態(tài)、功能和說明。默認(rèn)情況下,有多個(gè)仿真設(shè)備。我將介紹如何注冊新的非仿真硬件。注冊設(shè)備若要注冊設(shè)備,請按解決方案門戶中左下角的“添加設(shè)備”超鏈接。然后,選擇添加仿真設(shè)備還是自定義設(shè)備。選取第二個(gè)選項(xiàng),然后按“添加新設(shè)備”按鈕?,F(xiàn)在,可以定義“設(shè)備 ID”了。我將此值設(shè)置為“RemoteCamera”。此后,“添加自定義設(shè)備”窗體中顯示設(shè)備憑據(jù)(見圖 9),稍后用它將 IoT 設(shè)備連入 IoT 中心。圖 9:設(shè)備注冊摘要設(shè)備元數(shù)據(jù)和云通信添加的設(shè)備顯示在設(shè)備列表中,然后便可以發(fā)送設(shè)備元數(shù)據(jù)或設(shè)備信息。設(shè)備信息包括描述遠(yuǎn)程設(shè)備的 JSON 對象。此對象可告知云終結(jié)點(diǎn)設(shè)備功能,并包含硬
24、件描述以及設(shè)備接受的遠(yuǎn)程命令列表。最終用戶可通過 IoT 解決方案門戶向設(shè)備發(fā)送這些命令。在 RemoteCamera 應(yīng)用中,設(shè)備信息表示為 DeviceInfo 類(位于 AzureHelpers 子文件夾中):public class DeviceInfo public bool IsSimulatedDevice get; set; public string Version get; set; public string ObjectType get; set; public DeviceProperties DeviceProperties get; set; public Com
25、mand Commands get; set; DeviceInfo 的前兩個(gè)屬性指定了是否為仿真設(shè)備,并定義了 DeviceInfo 對象的版本。稍后可以看到,第三個(gè)屬性 ObjectType 被設(shè)置為字符串常數(shù) DeviceInfo。云(特別是 Azure 流分析作業(yè))使用此字符串從遙測數(shù)據(jù)中篩選出設(shè)備信息。接下來,DeviceProperties(見 AzureHelpers 子文件夾)包含一系列描述設(shè)備的屬性(如序列號、內(nèi)存、平臺、RAM)。最后,Commands 屬性包含設(shè)備識別的一系列遠(yuǎn)程命令。通過指定名稱和參數(shù)列表(分別由 Command 和 CommandParameter 類
26、表示,見 AzureHelpersCommand.cs),可定義每個(gè)命令。若要在 IoT 設(shè)備和 IoT 中心之間建立通信,請使用 Microsoft.Azure.Devices.Client NuGet 包。此包提供 DeviceClient 類,可用于向云發(fā)送消息和接收云消息。可以使用 Create 或 CreateFromConnectionString 靜態(tài)方法,創(chuàng)建 DeviceClient 實(shí)例。在本文中,我使用第一個(gè)選項(xiàng)(見 AzureHelpers 文件夾中的 CloudHelper.cs):public async Task Initialize() if (!IsIniti
27、alized) deviceClient = DeviceClient.Create( Configuration.Hostname, Configuration.AuthenticationKey(); await deviceClient.OpenAsync(); IsInitialized = true; BeginRemoteCommandHandling(); 可以看到,若要使用 DeviceClient.Create 方法,需要提供 IoT 中心的主機(jī)名和設(shè)備憑據(jù)(標(biāo)識符和密鑰)。這些值是在設(shè)備預(yù)配期間從解決方案門戶獲取(再次見圖 9)。在 RemoteCamera 應(yīng)用中,我在
28、Configuration 靜態(tài)類中存儲了主機(jī)名、設(shè)備 ID 和密鑰:public static class Configuration public static string Hostname get; = .; public static string DeviceId get; = RemoteCamera; public static string DeviceKey get; = ; public static DeviceAuthenticationWithRegistrySymmetricKey AuthenticationKey() return new DeviceAuth
29、enticationWithRegistrySymmetricKey(DeviceId, DeviceKey); 此外,Configuration 類還會實(shí)現(xiàn)靜態(tài)方法 AuthenticationKey,從而將設(shè)備憑據(jù)包裝到 DeviceAuthenticationWithRegistrySymmetricKey 類的實(shí)例中。我借此來簡化 DeviceClient 類實(shí)例的創(chuàng)建工作。連接建立后,只需發(fā)送 DeviceInfo 即可,如圖 10所示。圖 10:發(fā)送設(shè)備信息public async Task SendDeviceInfo() var deviceInfo = new DeviceI
30、nfo() IsSimulatedDevice = false, ObjectType = DeviceInfo, Version = 1.0, DeviceProperties = new DeviceProperties(Configuration.DeviceId), / Commands collection Commands = new Command CommandHelper.CreateCameraPreviewStatusCommand() ; await SendMessage(deviceInfo);RemoteCamera 應(yīng)用可發(fā)送描述實(shí)際硬件的設(shè)備信息,因此 IsS
31、imulatedDevice 屬性設(shè)置為 false。如上所述,ObjectType 設(shè)置為 DeviceInfo。此外,我還將 Version 屬性設(shè)置為 1.0。對于 DeviceProperties,我使用的是任意值,主要包括靜態(tài)字符串(見 DeviceProperties 類的 SetDefaultValues 方法)。我還定義了遠(yuǎn)程命令“更新攝像頭預(yù)覽”,以便能夠遠(yuǎn)程控制攝像頭預(yù)覽。此命令包含一個(gè)布爾參數(shù) IsPreviewActive,用于指定應(yīng)啟動(dòng)還是停止攝像頭預(yù)覽(見 AzureHelpers 文件夾下的 CommandHelper.cs 文件)。為了能夠真正將數(shù)據(jù)發(fā)送到云中,
32、我實(shí)現(xiàn)了 SendMessage 方法:private async Task SendMessage(Object message) var serializedMessage = MessageHelper.Serialize(message); await deviceClient.SendEventAsync(serializedMessage);一般來說,需要將 C# 對象序列化成包含 JSON 格式對象的字節(jié)數(shù)組(見 AzureHelpers 子文件夾中的 MessageHelper 靜態(tài)類):public static Message Serialize(object obj) A
33、rgumentCheck.IsNull(obj, obj); var jsonData = JsonConvert.SerializeObject(obj); return new Message(Encoding.UTF8.GetBytes(jsonData);然后,將生成的數(shù)組包裝到 Message 類中,以使用 DeviceClient 類實(shí)例的 SendEventAsync 方法將其發(fā)送到云中。Message 類是對象,為原始數(shù)據(jù)(傳輸?shù)?JSON 對象)補(bǔ)充了其他屬性。這些屬性用于跟蹤設(shè)備與 IoT 中心之間發(fā)送的消息。在 RemoteCamera 應(yīng)用中,與云建立連接和發(fā)送設(shè)備信息
34、是通過“云”選項(xiàng)卡上的兩個(gè)按鈕觸發(fā)的: “連接和初始化”和“發(fā)送設(shè)備信息”。第一個(gè)按鈕的 click 事件處理程序綁定到 RemoteCameraViewModel 的 Connect 方法:public async Task Connect() await CloudHelper.Initialize(); IsConnected = true;第二個(gè)按鈕的 click 事件處理程序與 CloudHelper 類實(shí)例的 SendDeviceInfo 方法相關(guān)聯(lián)。此方法前面介紹過。連入云后,還可以開始發(fā)送遙測數(shù)據(jù),與發(fā)送設(shè)備信息相似。也就是說,可以使用 SendMessage 方法,向其傳遞遙
35、測對象。在本文中,此對象是 TelemetryData 類的實(shí)例,只有一個(gè)屬性 Brightness。下面的完整示例展示了如何將遙測數(shù)據(jù)發(fā)送到云中,具體是在 CloudHelper 類的 SendBrightness 方法內(nèi)實(shí)現(xiàn):public async void SendBrightness(byte brightness) if (IsInitialized) / Construct TelemetryData var telemetryData = new TelemetryData() Brightness = brightness ; / Serialize TelemetryDat
36、a and send it to the cloud await SendMessage(telemetryData); 在獲取 ImageProcessor 計(jì)算的亮度后,便會立即調(diào)用 SendBrightness。ProcessingDone 事件處理程序負(fù)責(zé)執(zhí)行此操作:private void ImageProcessor_ProcessingDone(object sender, ImageProcessorEventArgs e) / Update display through dispatcher DisplayBrightness(e.Brightness); / Send t
37、elemetry if (remoteCameraViewModel.IsTelemetryActive) remoteCameraViewModel.CloudHelper.SendBrightness(e.Brightness); 因此,如果現(xiàn)在運(yùn)行 RemoteCamera 應(yīng)用,然后開始預(yù)覽并連接云,將會看到亮度值顯示在相應(yīng)圖表中,如圖 1所示。請注意,盡管預(yù)配置解決方案的仿真設(shè)備旨在以遙測數(shù)據(jù)形式發(fā)送溫度和濕度,但也可以發(fā)送其他值。在本文中,我將發(fā)送亮度,它會自動(dòng)顯示在相應(yīng)圖表中。處理遠(yuǎn)程命令CloudHelper 類還實(shí)現(xiàn)方法來處理從云中收到的遠(yuǎn)程命令。同樣,與 ImageProc
38、essor 一樣,我是在后臺處理命令(見 CloudHelper 類的 BeginRemoteCommandHandling)。我將再次使用基于任務(wù)的異步模式:private void BeginRemoteCommandHandling() Task.Run(async () = while (true) var message = await deviceClient.ReceiveAsync(); if (message != null) await HandleIncomingMessage(message); );此方法負(fù)責(zé)創(chuàng)建任務(wù)來持續(xù)分析從云終結(jié)點(diǎn)收到的消息。若要接收遠(yuǎn)程消息,請
39、調(diào)用 DeviceClient 類的 ReceiveAsync 方法。ReceiveAsync 返回 Message 類的實(shí)例,可用于獲取包含 JSON 格式遠(yuǎn)程命令數(shù)據(jù)的原始字節(jié)數(shù)組。然后,將此數(shù)組反序列化成 RemoteCommand 對象(見 AzureHelpers 文件夾中的 RemoteCommand.cs),具體是在 MessageHelper 類(見 AzureHelpers 子文件夾)中進(jìn)行實(shí)現(xiàn):public static RemoteCommand Deserialize(Message message) ArgumentCheck.IsNull(message, mess
40、age); var jsonData = Encoding.UTF8.GetString(message.GetBytes(); return JsonConvert.DeserializeObject( jsonData);雖然 RemoteCommand 包含多個(gè)屬性,但通常只使用以下兩個(gè):名稱和參數(shù)(其中包含命令名稱和命令參數(shù))。在 RemoteCamera 應(yīng)用中,我使用這些值來確定是否按預(yù)期接收到了命令(見圖 11)。如果收到,我會觸發(fā) UpdateCameraPreviewCommandReceived 事件,將相應(yīng)信息傳遞給偵聽器,然后我會使用 DeviceClient 類的 C
41、ompleteAsync 方法,通知云已收到命令。如果命令無法識別,我會使用 RejectAsync 方法拒絕接收。圖 11:遠(yuǎn)程消息反序列化和分析private async Task HandleIncomingMessage(Message message) try / Deserialize message to remote command var remoteCommand = MessageHelper.Deserialize(message); / Parse command ParseCommand(remoteCommand); / Send confirmation to the cloud await deviceClient.CompleteAsync(message); catch (Exception ex) Debug.WriteLine(ex.Message); / Reject message, if it was not parsed correctly await deviceClient.RejectAsync(message); private
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 隱私增強(qiáng)學(xué)習(xí)技術(shù)-洞察分析
- 2024年05月廣東浦發(fā)銀行總行社會招考(519)筆試歷年參考題庫附帶答案詳解
- 內(nèi)蒙古框架協(xié)議書范本(2篇)
- Java程序設(shè)計(jì)教程課件
- 《寶潔企業(yè)戰(zhàn)略管理》課件
- 2024年華東師大版八年級物理上冊階段測試試卷
- 《安全文化與安全》課件
- 2024年明光市人民醫(yī)院高層次衛(wèi)技人才招聘筆試歷年參考題庫頻考點(diǎn)附帶答案
- 2025年蘇人新版必修2地理上冊階段測試試卷
- 2025年粵教版八年級歷史上冊階段測試試卷
- 第二章 粉體制備
- 預(yù)應(yīng)力空心板計(jì)算
- GA/T 1740.2-2024旅游景區(qū)安全防范要求第2部分:湖泊型
- 2023年開封糧食產(chǎn)業(yè)集團(tuán)有限公司招聘筆試真題
- 2024年全國“紀(jì)檢監(jiān)察”業(yè)務(wù)相關(guān)知識考試題庫(附含答案)
- 2025年社區(qū)工作者考試試題庫及答案
- 期末檢測卷(三)2024-2025學(xué)年人教PEP版英語四年級上冊(含答案無聽力原文無聽力音頻)
- 2024-2030年中國兒童內(nèi)衣行業(yè)運(yùn)營狀況及投資前景預(yù)測報(bào)告
- 吉首大學(xué)《高等數(shù)學(xué)》2023-2024學(xué)年第一學(xué)期期末試卷
- 打印和復(fù)印服務(wù)協(xié)議
- 針灸習(xí)題庫(附參考答案)
評論
0/150
提交評論