IoT (internet of things) 的時代來臨,各式各樣的智能設備陸續出現在生活中。如何讓 App 可以找到這些設備? 有 mDNS(Multicast DNS) 跟 MQTT is a machine-to-machine (M2M)/Internet of Things 兩個技術協定,下面將介紹怎麽找設備。
mDNS 比較熟悉這塊的人一定會知道與他相關的 Bonjour,目的就是搜尋同一個網路有實作特定 Service Name 的設備。
mDNS 在 Windows 10 才開始支援(代表 UWP 就有機會處理),之前的版本需要而外安裝。
我參考 DNS-SD(Bonjour)をUniversal Windows Platformから利用してサービスを探す 來瞭解怎麽利用 DeviceWatcher 來找到設備。
如下程式碼片段:
// DNS-SDのサービス名
var serviceName = "_androidtvremote._tcp";
// DNS-SDを利用する
var protocolId = "{4526e8c1-8aac-4153-9b16-55e86ada0e54}";
// デバイス検索文字列
var aqsFilter = $"System.Devices.AepService.ProtocolId:={protocolId} AND System.Devices.Dnssd.Domain:=\"local\" AND System.Devices.Dnssd.ServiceName:=\"{serviceName}\"";
// 取得するプロパティ
var properties = new[] {
"System.Devices.Dnssd.HostName", // ホスト名 (自称)
"System.Devices.IpAddress", // IPアドレスの配列(string[])
};
var watcher = DeviceInformation.CreateWatcher(aqsFilter, properties, DeviceInformationKind.AssociationEndpointService);
上述的 code 有很多東西我沒有看過,要瞭解這些問題,先介紹用到的元素:
- DeviceInformation
代表一個設備,允許訪問已知的裝置屬性以及其他列舉過程中指定的屬性。
由 DeviceInformation.Id,DeviceInformation.Kind 與 DeviceInformation.Properties 組合合成。
DeviceInformation 類別提供設備資訊,具體來説,它是提供一個 device interface 裏面含有多個屬性,也代表該設備公開的屬性;
一個多功能設備可能實作多個 device interface。使用時可以被該類別當作是一種容易裏面包含多種設備資訊。
Name Description Id 代表一個設備擁有的 device interface 識別值。 Id 可以被用來搭配 CreateFromIdAsync 直接建立特定設備資訊。 Kind 代表 DeviceInformationKind 的類型。 Name 代表設備名稱,由於可能被用戶改變,不建議用來當作識別值。 Properties 包含一些已知或是 device enumeration 過程中發現的特殊屬性。 採用 Dictionary 的結構, key 有哪些呢?可以參考 Device information properties CreateWatcher(String, IIterable , DeviceInformationKind) aqsFileter: Advanced Query Syntax (AQS) 字串,作爲過濾那些 DeviceInformation 用。字串可從 GetDeviceSelector 檢索而來,例如:GetDeviceSelector 可以檢索 StorageDevice 類別的字串。 additionalProperties: 列舉清單,主要寫入檢索設備時那些特殊的屬性需要具備。詳細的資料來自 Device information properties。 kind: DeviceInformationKind 設定 DeviceWatcher 的類型。 此 method 會建立 DeviceWatcher。 FindAllAsync(String, IIterable , DeviceInformationKind) 參數跟 CreateWatcher(String, IIterable , DeviceInformationKind) 一樣,不同在於直接回傳搜尋後的 DeviceInformationCollection>。
- DeviceWatcher
動態列舉出設備, DeviceWatcher 在初始化完成後會收到一些通知 (例如:設備被找到,更新,刪除等)。
DeviceWatcher 呼叫了 Start() 開始搜尋設備,需要去註冊: Added, Removed, Updated 事件處理設備的加入/刪除/更新資訊。
如果 EnumerationCompleted 事件被觸發,DeviceWatcher 依舊會持續搜尋設備。
下面截取 DeviceWatcher 介紹它的運作流程:
使用上有幾個地方要注意:- Start() 只能在 DeviceWatcher 在 created, stopped or aborted 狀態使用;如果要 restart 需要先等到 Stopped 事件被呼叫之後。
- 呼叫 Stop() 會立刻進去 sopped 狀態與立刻完成搜尋。
- App 一定要註冊處理 added, removed 與 updated 事件才能完整處理到所有的設備;如果只有註冊 added 可能會在 EnumerationCompleted 事件觸發後漏掉一些設備的更新或是加入。
知道元素的用途之後,我有下面的問題:
- aqsFilter 是什麽?
利用 Advanced Query Syntax (AQS) 字串去定義要搜尋特定 DeviceInformation 物件的條件。(語法可以參考 Using Advanced Query Syntax Programmatically)
System.Devices.AepService.ProtocolId System.Devices.Dnssd.Domain System.Devices.Dnssd.ServiceName
分別又是什麽意思? 根據 Enumerate devices over a network 介紹,我們需要用到的是 DNS service discovery (DNS-SD) = {4526e8c1-8aac-4153-9b16-55e86ada0e54},
利用這個值去設定 DeviceInformationKind 要搜尋的是什麽類型。
另外如果有需要定義到 AEP service class ID 的話,可以從 Association Endpoint (AEP) service class IDs 找到有支援的 service class IDs。
System.Devices.Dnssd.Domain 定義了 DNS-SD 服務實例名稱的區域部分,例如:".local" in "myservice._http._tcp.local"。
System.Devices.Dnssd.ServiceName定義了 DNS-SD 服務實例名稱的服務類型部分,例如:"_http._tcp" in "myservice._http._tcp.local"。
- properties 的字串怎麽來?
Device information properties 提到每一個設備都有 DeviceInformation properties,因此做搜尋設備時可以加入要搜尋具有特定 properties 的設備,例如: Build a device selector 介紹。 另外更可以指定 Devices 的屬性去做搜尋。
[補充]
- mDNS(Multicast DNS) & Bonjour
由 Apple 所制定的技術集合 (zero-configuration networking (zeroconf)),包括: service discovery, address assignment, hostname resolution。
常用來找附近的 prints, other computer 與在這個 local network 下利用 mDNS(multicast domain name system) 可以找到的服務。
mDNS protocol 利用 IP multicast UDP 在網段中廣播詢問有辦法處理這個協定的設備,例如:Apple Bonjour, open source Avahi。
mDNS 可以結合 DNS Service Discovery (DNS-SD) 技術一起使用。 - MQTT(MQ Telemetry Transport or Message Queue Telemetry Transport)
一個運作在 TCP/IP protocol 上的輕量型(lightweight)訊息交換協定,在 machine-to-machine (M2M)/"Internet of Things" 的環境很常被使用。
運作架構是: publish-subscribe messaging pattern 為主軸,兩者主要透過 topic 的方式互相溝通:
1. subscriber 可以訂閲(subscribe) 要處理的 topic
2. publisher 發送訊息到 topic
3. message broker 負責收到訊息之後發佈給 subscribe 的 subscriber
更多説明可以參考: MQTT 簡介。 - 重要的 Namespaces
======
這篇是我開發過程遇到的問題,如果有不正確的地方也歡迎指教。謝謝。 References:
- Devices, sensors, and power
- Windows.Networking.ServiceDiscovery.Dnssd Namespace
- Eclipse open source for IoT
- Enumerate devices
- Build a device selector
- Device information properties
- Enumerate devices over a network
- AEP service class IDs
- Windows.Devices.Enumeration Namespace
- Device information properties
- Windows Property System > Property System Reference > Windows Properties > Devices
- eclipse/paho.mqtt.m2mqtt
- Protocol Buffers .NET Runtime Library API Reference
- DNS-SD(Bonjour)をUniversal Windows Platformから利用してサービスを探す
- Custom USB device sample (Windows 10)
- Advertising WSD printers via mDNS and DNS-SD records
- AEP service class IDs
- Advanced Query Syntax (AQS)
- Using Advanced Query Syntax Programmatically
- Build a device selector