UWP - mDNS 找尋附近的設備

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.IdDeviceInformation.KindDeviceInformation.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 事件觸發後漏掉一些設備的更新或是加入。

知道元素的用途之後,我有下面的問題:

[補充]

  • 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: