Azure 事件方格的 MQTT 代理功能支援的 MQTT 功能
MQTT 是一種發佈-訂閱傳訊傳輸通訊協定,專為受限制的環境所設計。 它是有效率、可調整且可靠的,因此成為 IoT 案例中通訊的黃金標準。 MQTT 代理支援透過 MQTT v3.1.1、透過 WebSocket 的 MQTT v3.1.1、MQTT v5 和透過 WebSockets 的 MQTT v5 發佈和訂閱訊息的用戶端。 MQTT 代理也支援跨 MQTT 版本 (MQTT 3.1.1 和 MQTT 5) 通訊。
MQTT v5 引進了許多 MQTT v3.1.1 的功能改善,提供更順暢、透明且有效率的通訊。 它已新增:
- 更好的錯誤報告。
- 透過使用者屬性和內容類型等功能,提供更透明的通訊用戶端。
- 透過訊息和工作階段到期等功能,更能控制用戶端的通訊。
- 標準的重要模式,例如要求-回應模式。
線上流程:
MQTT 用戶端必須透過 TLS 1.2 或 TLS 1.3 連線。 嘗試略過此步驟會發生連線失敗。
連線至 MQTT 代理時,透過 MQTT 進行通訊時,請使用下列連接埠:
- TCP 連接埠 8883 上的 MQTT v3.1.1 和 MQTT v5
- TCP 連接埠 443 上透過 WebSocket 的 MQTT v3.1.1 和透過 WebSocket 的 MQTTv5。
CONNECT 封包應該包含下列屬性:
- [ClientId] 欄位是必要的,且其應該包含用戶端的工作階段名稱。 工作階段名稱在整個命名空間中必須是唯一的。 如果每個用戶端對於每個用戶端使用一個工作階段,您可以使用用戶端驗證名稱作為工作階段名稱。 如果一個用戶端使用多個工作階段,它必須針對每個工作階段使用不同的 ClientId 值。
- 如果您在命名空間建立期間未選取 alternativeAuthenticationNameSources 中的值,則需要 [使用者名稱] 欄位。 在此情況下,您必須在 [使用者名稱] 欄位中提供用戶端的驗證名稱。 該名稱必須符合提供的驗證名稱,以及用戶端憑證欄位中在用戶端資源建立期間指定的值。
深入了解用戶端驗證。
多工作階段支援
多工作階段支援可讓應用程式 MQTT 用戶端同時連線到具有多個作用中工作階段的 MQTT 代理,以擁有更加可調整且可靠的實作。
命名空間設定
使用這項功能之前,您必須設定命名空間,以允許每個用戶端的多個工作階段。 使用下列步驟在 Azure 入口網站中設定每個用戶端的多個工作階段:
- 在 Azure 入口網站中,移至您的命名空間。
- 在 [設定] 下,將 [每個驗證名稱的用戶端工作階段上限] 的值變更為每個用戶端所需的工作階段數目。
- 選取 [套用] 。
注意
針對 Azure CLI 設定,使用所需的值更新命名空間承載中的 MaxClientSessionsPerAuthenticationName 屬性。
線上流程:
每個工作階段的 CONNECT 封包應該包含下列屬性:
- 在 CONNECT 封包中提供 Username 屬性,以表示用戶端驗證名稱。
- 在 CONNECT 封包中提供 ClientID 屬性,以表示工作階段名稱,例如每個 Username 的 ClientID 有一或多個值。
例如,CONNECT 封包中的下列 Username 和 ClientId 組合可讓用戶端 “Mgmt-application” 透過三個獨立的工作階段連線到 MQTT 代理:
- 第一個工作階段:
- 使用者名稱:
Mgmt-application
- ClientId:
Mgmt-Session1
- 使用者名稱:
- 第二個工作階段:
- 使用者名稱:
Mgmt-application
- ClientId:
Mgmt-Session2
- 使用者名稱:
- 第三個工作階段:
- 使用者名稱:
Mgmt-application
- ClientId:
Mgmt-Session3
- 使用者名稱:
如需詳細資訊,請參閱如何為單一用戶端建立多個工作階段。
處理工作階段:
- 如果用戶端嘗試以不同的驗證名稱呈現其工作階段名稱來接管另一個用戶端的作用中工作階段,則會拒絕其連線要求,並出現未經授權的錯誤。 例如,如果用戶端 B 嘗試連線到當時針對用戶端 A 指派的工作階段 123,用戶端 B 的連線要求就會遭到拒絕。 也就是說,如果相同的用戶端嘗試使用相同的工作階段名稱和相同的驗證名稱重新連線,它就能夠接管其現有的工作階段。
- 如果刪除用戶端資源而不結束其工作階段,則其他用戶端將無法使用其工作階段名稱,直到工作階段到期為止。 例如,如果用戶端 B 建立工作階段名稱為 123 的工作階段,之後用戶端 B 遭到刪除,則用戶端 A 在到期前無法連線到工作階段 123。
- 每個用戶端的工作階段數目限制適用於任何時間點的線上和離線工作階段。 例如,假設命名空間的每個驗證名稱用戶端工作階段數上限設定為 1。 如果用戶端 A 與持續性工作階段 123 連線,然後中斷連線,則用戶端 A 將無法連線到新的工作階段 456,因為其工作階段 123 仍然處於作用中狀態,即使它已離線也一樣。 因此,我們建議相同的用戶端一律使用相同的靜態工作階段名稱重新連線,而不是每次重新連線產生新的工作階段名稱。
MQTT 功能
Azure 事件方格的 MQTT 代理功能支援下列 MQTT 功能:
服務品質 (QoS)
MQTT 代理支援 QoS 0 和 1,其定義了用戶端與 MQTT 代理之間 PUBLISH 和 SUBSCRIBE 封包的保證。 QoS 0 保證最多一次傳遞;訂閱者不會認可具有 QoS 0 的訊息,也不會由發行者重新傳輸。 QoS 1 保證至少一次傳遞;如果訊息未獲得認可,則訂閱者會認可訊息,並由發行者重新傳輸。 QoS 可讓用戶端控制通訊的效率和可靠性。
持續性工作階段
MQTT 代理支援 MQTT v3.1.1 的持續性工作階段,讓 MQTT 代理在中斷連線時保留用戶端工作階段的相關資訊,以確保通訊的可靠性。 此資訊包括用戶端的訂用帳戶,以及遺漏/未認可的 QoS 1 訊息。 用戶端可以透過將 CONNECT 封包中的 cleanSession 旗標設定為 false 來設定持續性工作階段。
清除啟動和工作階段到期
MQTT v5 引進了全新開始和工作階段到期功能,以改進處理工作階段持續性的 MQTT v3.1.1。 全新開始是一項功能,可讓用戶端使用 MQTT 代理開始新的工作階段,並捨棄任何先前的工作階段資料。 工作階段到期可讓用戶端在非使用中工作階段視為已過期並自動移除時通知 MQTT 代理。 在 CONNECT 封包中,用戶端可以基於安全性考量,將 [全新開始] 旗標設定為 true 和/或短時間工作階段到期間隔,或避免在上一個工作階段期間可能發生的任何潛在資料衝突。 用戶端也可以將全新開始設定為 false 和/或長時間工作階段到期間隔,以確保持續性工作階段的可靠性與效率。
工作階段到期間隔設定上限
您可以設定連線到事件方格命名空間的所有用戶端允許的工作階段到期間隔上限。 針對 MQTT v3.1.1 用戶端,設定的限制會套用為所有持續性工作階段的預設工作階段到期間隔。 針對 MQTT v5 用戶端,設定的限制會套用為 CONNECT 封包中工作階段到期間隔屬性的最大值;任何超過限制的值都會進行調整。 這個命名空間屬性的預設值為 1 小時,最多可以延長至 8 小時。 使用下列步驟在 Azure 入口網站中設定工作階段到期間隔上限:
- 在 Azure 入口網站中,移至您的命名空間。
- 在 [設定] 下,將 [工作階段到期間隔上限 (小時)] 的值變更為所需的限制。
- 選取套用。
工作階段溢位
MQTT 代理會針對未連線的每個作用中 MQTT 工作階段維護訊息佇列,直到用戶端再次與 MQTT 代理連線,以接收佇列中的訊息。 如果用戶端未連線以接收佇列 QOS1 訊息,工作階段佇列就會開始累積訊息,直到達到其限制為止:100 則訊息或 1 MB。 一旦佇列在工作階段的存留期達到其限制,工作階段就會終止。
最後遺囑 (LWT) 訊息
最後遺囑 (LWT) 會向您的 MQTT 用戶端通知其他 MQTT 用戶端突然中斷連線。 您可以使用 LWT 來確保 MQTT 用戶端在非預期的中斷連線期間維持可預測且可靠的通訊流程,這對於注重即時通訊、系統可靠性和協調動作的案例而言相當重要。 透過共同作業來執行複雜工作的用戶端可以藉由調整其行為、重新分配工作,或接管特定責任來回應彼此的 LWT 訊息,以維持系統的效能和穩定性。 若要使用 LWT,用戶端可以指定遺囑訊息、遺囑主題,以及連線期間 CONNECT 封包中其餘的遺囑屬性。 當用戶端突然中斷連線時,MQTT 代理會將遺囑訊息發佈給訂閱該遺囑主題的所有用戶端。 若要減少來自中斷連線變動的干擾,用戶端可以將遺囑延遲間隔設定為大於零的值。 在此情況下,如果用戶端突然中斷連線,但在遺囑延遲間隔到期之前即恢復連線,則不會發佈遺囑訊息。
使用者屬性
MQTT 代理支援 MQTT v5 PUBLISH 封包上的使用者屬性,可讓您在訊息標頭中新增自訂索引鍵/值組,以提供更多關於訊息的內容。 使用者屬性的使用案例是多用途的。 您可以使用這項功能來包含訊息的用途或來源,讓接收者可以處理訊息,而不需要剖析承載、同時節省計算資源。 例如,具有使用者屬性,指出其用途為「警告」的訊息,可能會觸發與具有「資訊」目的不同處理邏輯。
要求-回應模式
MQTTv5 引進 MQTT PUBLISH 封包標頭中的欄位,可在要求-回應模式中提供回應訊息的內容。 這些欄位包括回應主題,以及回應者可在回應中使用且不需要事先設定的相互關聯識別碼。 回應資訊可為命令和控制案例中使用的標準要求-回應模式實現更有效率的通訊。
訊息到期間隔:
在 MQTT v5 中,訊息到期間隔可讓訊息具有可設定的存留期。 訊息到期間隔的定義是訊息發佈至 MQTT 代理的時間,以及 MQTT 代理在必須捨棄未抵達訊息的時間之間的時間間隔。 這項功能適用於訊息只在特定時間長度有效的案例,例如區分時間的命令、即時資料串流或安全性警示。 透過設定訊息到期間隔,MQTT 代理可以自動移除過期的訊息,確保只有相關資訊可供訂閱者使用。 如果訊息的到期間隔設定為零,表示訊息不應該過期。
主題別名:
在 MQTT v5 中,主題別名可讓用戶端使用較短的別名來取代已發佈訊息中的完整主題名稱。 MQTT 代理會維護主題別名與實際主題名稱之間的對應。 這項功能可以節省網路頻寬,並減少訊息標頭的大小,特別是針對具有長名稱的主題。 在多個訊息中重複發佈相同主題的案例中,例如在感應器網路中,這非常有用。 MQTT 代理最多支援 10 個主題別名。 用戶端可以使用 PUBLISH 封包中的 [主題別名] 欄位,將完整主題名稱取代為對應的別名。
流程控制
在 MQTT v5 中,流量控制是指管理用戶端可處理的訊息速率和大小的機制。 您可以在 CONNECT 封包中設定 [封包大小上限] 和 [接收上限] 參數,以設定流量控制。 [接收上限] 參數可讓用戶端將訊息代理程式所傳送的訊息數目限制為用戶端能夠處理的訊息數目。 [封包大小上限] 參數會定義用戶端可接收的封包大小上限。 MQTT 代理有 512 KiB 的訊息大小限制。 這項功能可確保受限裝置的通訊可靠性和穩定性,但處理速度或儲存功能有限。
否定性通知和伺服器起始的中斷連線封包
針對 MQTT v5,MQTT 代理能夠傳送否定性通知 (NACK) 和伺服器起始的中斷連線封包,以提供用戶端訊息傳遞或連線失敗的詳細資訊。 這些功能可協助用戶端診斷失敗背後的原因,並採取適當的緩解動作。 MQTT 代理會使用 MQTT v5 規格中定義的原因代碼。
目前的限制
MQTT 代理未來會新增更多 MQTT v5 和 MQTTv3.1.1 功能,以配合 MQTT 規格的更多要求。 下列清單詳細說明 MQTT 代理和 MQTT 規格所支援功能之間的目前差異:
MQTTv5 目前的限制
MQTT v5 目前與 MQTT v5 規格不同,如下所述:
- 尚不支援共用訂閱。
- 尚不支援保留旗標。
- 遺囑延遲間隔的上限為 300。
- 最大 QoS 為 1。
- 封包大小上限為 512 KiB
- 不保證訊息順序。
- 不支援訂閱識別碼。
- 尚未支援指派的用戶端識別碼。
- 主題別名的最大值為 10。 伺服器目前不會為傳出訊息指派任何主題別名。 用戶端可以在設定限制內指派和使用主題別名。
- 即使 CONNECT 要求包含要求回應資訊屬性,CONNACK 也不會傳回回應資訊屬性。
- 服務不會使用 CONNECT、SUBSCRIBE、DISCONNECT、PUBACK、AUTH 封包上的使用者屬性,因此不受支援。 如果其中任何一個要求包含使用者屬性,則要求會失敗。
- 如果伺服器從具有非成功回應碼的用戶端收到 PUBACK,則會終止連線。
- 保持運作上限為 1,160 秒。
MQTTv3.1.1 目前的限制
MQTT v5 目前與 MQTT v3.1.1 規格不同,如下所述:
- 尚不支援 QoS2 和保留旗標。 具有保留旗標或 QoS2 的發行要求會失敗並關閉連線。
- 不保證訊息順序。
- 保持運作上限為 1,160 秒。
程式碼範例:
此存放庫包含 C#、C 和 Python 程式碼範例,示範如何傳送遙測、傳送命令和廣播警示。 透過範例建立的憑證適合用於測試,但不適合用於實際執行環境。
後續步驟:
深入了解 MQTT:
深入了解 MQTT 代理: