Sdílet prostřednictvím


Protokol úložiště stavů

Úložiště stavů je distribuovaný systém úložiště v rámci clusteru Azure IoT Operations. Úložiště stavů nabízí stejné záruky vysoké dostupnosti jako zprávy MQTT ve zprostředkovateli MQTT. Podle pokynů pro protokol MQTT5/RPC by klienti měli používat MQTT5 k interakci s úložištěm stavů. Tento článek obsahuje pokyny k protokolům pro vývojáře, kteří potřebují implementovat vlastní klienty úložiště stavů.

Přehled

Úložiště stavů podporuje následující příkazy:

  • SET<keyName><keyValue><setOptions>
  • GET<keyName>
  • DEL<keyName>
  • VDEL<keyName><keyValue> ## Odstraní daný <název klíče> , pokud a pouze pokud je <jeho hodnota keyValue.>

Protokol používá následující model odpovědi na požadavky:

  • Žádost. Klienti publikují požadavek do dobře definovaného tématu systému úložiště stavů. K publikování požadavku používají klienti požadované vlastnosti a datovou část popsanou v následujících částech.
  • Response (Odpověď). Úložiště stavů asynchronně zpracovává požadavek a reaguje na téma odpovědi, které klient původně poskytl.

Následující diagram znázorňuje základní zobrazení požadavku a odpovědi:

Diagram základního procesu žádosti a odpovědi úložiště stavu

Téma systému úložiště stavů, QoS a požadované vlastnosti MQTT5

Aby klienti mohli komunikovat s úložištěm stavů, musí splňovat následující požadavky:

  • Použijte MQTT5. Další informace najdete ve specifikaci MQTT 5.
  • Používejte QoS 1 (úroveň kvality služeb 1). QoS 1 je popsáno ve specifikaci MQTT 5.
  • Mají hodiny, které jsou do jedné minuty od hodin zprostředkovatele MQTT.

Ke komunikaci s úložištěm stavu musí PUBLISH klienti požádat o systémové téma statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/command/invoke. Vzhledem k tomu, že úložiště stavů je součástí operací Azure IoT, implicitně SUBSCRIBE se k tomuto tématu při spuštění používá.

K sestavení požadavku se vyžadují následující vlastnosti MQTT5. Pokud tyto vlastnosti nejsou k dispozici nebo požadavek není typu QoS 1, požadavek selže.

  • Téma odpovědi Úložiště stavů reaguje na počáteční požadavek pomocí této hodnoty. Osvědčeným postupem je naformátovat téma odpovědi jako clients/{clientId}/services/statestore/_any_/command/invoke/response. Nastavení tématu odpovědi jako statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/command/invoke nebo jako tématu, které začíná clients/statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8 na požadavku úložiště stavů, není povoleno. Úložiště stavů odpojí klienty MQTT, kteří používají neplatné téma odpovědi.
  • Data korelace. Když úložiště stavů odešle odpověď, obsahuje data korelace počátečního požadavku.

Následující diagram znázorňuje rozšířené zobrazení požadavku a odpovědi:

Diagram rozšířeného procesu žádosti a odpovědi úložiště stavů

Podporované příkazy

Příkazy SETa GETDEL chovají se podle očekávání.

Hodnoty, které SET příkaz nastaví a GET příkaz načte, jsou libovolná binární data. Velikost hodnot je omezena pouze maximální velikostí datové části MQTT a omezeními prostředků zprostředkovatele MQTT a klienta.

SET volby

Příkaz SET poskytuje další volitelné příznaky nad rámec základního keyValue příznaku a keyName:

  • NX. Umožňuje nastavit klíč jenom v případě, že ještě neexistuje.
  • NEX <value>. Umožňuje nastavit klíč pouze v případě, že klíč neexistuje nebo pokud je hodnota klíče už nastavená na <hodnotu>. Příznak NEX se obvykle používá pro klienta, který prodlužuje platnost klíče (PX).
  • PX. Jak dlouho má klíč trvat, než vyprší jeho platnost, v milisekundách.

VDEL volby

Příkaz VDEL je zvláštní případ DEL příkazu. DEL nepodmíněně odstraní dané keyName. VDEL vyžaduje jiný argument s názvem keyValue. VDEL odstraní pouze danou, keyName pokud má stejnou keyValue.

Formát datové části

Formát datové části úložiště PUBLISH stavů je inspirovaný resp3, což je základní protokol, který Redis používá. RESP3 kóduje příkaz, například SET nebo GET, a parametry jako keyName a keyValue.

Rozlišování malých a velkých písmen

Klient musí odesílat příkazy i možnosti velkými písmeny.

Formát požadavku

Požadavky jsou formátované jako v následujícím příkladu. Následující RESP3 * představuje počet položek v poli. Znak $ je počet znaků v následujícím řádku s výjimkou koncového CRLF.

Podporované příkazy ve formátu RESP3 jsou GET, SET, DELa VDEL.

*{NUMBER-OF-ARGUMENTS}<CR><LF>
${LENGTH-OF-NEXT-LINE}<CR><LF>
{COMMAND-NAME}<CR><LF>
${LENGTH-OF-NEXT-LINE}<CR><LF> // This is always the keyName with the current supported verbs.
{KEY-NAME}<CR><LF>
// Next lines included only if command has additional arguments
${LENGTH-OF-NEXT-LINE}<CR><LF> // This is always the keyValue for set
{KEY-VALUE}<CR><LF>

Následující příklad výstupu ukazuje datové části ÚLOŽIŠTĚ stavu RESP3:

*3<CR><LF>$3<CR><LF>set<CR><LF>$7<CR><LF>SETKEY2<CR><LF>$6<CR><LF>VALUE5<CR><LF>
*2<CR><LF>$3<CR><LF>get<CR><LF>$7<CR><LF>SETKEY2<CR><LF>
*2<CR><LF>$3<CR><LF>del<CR><LF>$7<CR><LF>SETKEY2<CR><LF>
*3<CR><LF>$4<CR><LF>vdel<CR><LF>$7<CR><LF>SETKEY2<CR><LF>$3<CR><LF>ABC<CR><LF>

Poznámka:

SET vyžaduje další vlastnosti MQTT5, jak je vysvětleno v části Správa verzí a hybridní logické hodiny.

Formát odpovědi

Když úložiště stavů zjistí neplatnou datovou část RESP3, stále vrací odpověď na žadatele Response Topic. Mezi příklady neplatných datových částí patří neplatný příkaz, neplatný resp3 nebo celočíselné přetečení. Neplatná datová část začíná řetězcem -ERR a obsahuje další podrobnosti.

Poznámka:

Hodnota GET, DELnebo VDEL požadavek na neexistující klíč se nepovažuje za chybu.

Pokud klient odešle neplatnou datovou část, úložiště stavů odešle datovou část jako v následujícím příkladu:

-ERR syntax error

SET odpověď

SET Pokud požadavek proběhne úspěšně, úložiště stavů vrátí následující datovou část:

+OK<CR><LF>

Pokud požadavek SET selže, protože kontrola podmínky uvedená v možnostech sady NX nebo NEX, což znamená, že klíč nelze nastavit, vrátí úložiště stavů následující datovou část:

-1<CR><LF>

GET odpověď

GET Při provedení požadavku na neexistující klíč vrátí úložiště stavů následující datovou část:

$-1<CR><LF>

Po nalezení klíče vrátí úložiště stavů hodnotu v následujícím formátu:

${NumberOfBytes}<CR><LF>
{KEY-VALUE}

Výstup úložiště stavů vracející hodnotu 1234 vypadá jako v následujícím příkladu:

$4<CR><LF>1234<CR><LF>

DEL a VDEL odpověď

Úložiště stavů vrátí počet hodnot, které odstraní v žádosti o odstranění. Úložiště stavů v současné době může odstranit pouze jednu hodnotu najednou.

:{NumberOfDeletes}<CR><LF> // Will be 1 on successful delete or 0 if the keyName is not present

Následující výstup je příkladem úspěšného DEL příkazu:

:1<CR><LF>

Pokud požadavek VDEL selže, protože zadaná hodnota neodpovídá hodnotě přidružené k klíči, vrátí úložiště stavů následující datovou část:

-1<CR><LF>

-ERR odpovědi

Následuje aktuální seznam chybových řetězců. Klientská aplikace by měla zpracovávat neznámé chybové řetězce, aby podporovala aktualizace úložiště stavů.

Řetězec chyby vrácený z úložiště stavů Vysvětlení
časové razítko požadavku je v budoucnu příliš daleko; ujistěte se, že jsou synchronizovány systémové hodiny klienta a zprostředkovatele. Neočekávané časové razítko požadavku způsobené úložištěm stavu a hodiny klienta se nesynchronizují.
Pro tento požadavek se vyžaduje token pro proložení. K chybě dochází v případě, že je klíč označen tokenem pro ohraničení, ale klient nezadá token ohraničení.
časové razítko tokenu ohraničení požadavku je v budoucnu příliš daleko; ujistěte se, že jsou synchronizovány systémové hodiny klienta a zprostředkovatele. Neočekávaná časová razítka tokenu ohraničení způsobená úložištěm stavů a hodinami klienta se nesynchronizují.
token pro ohraničení požadavku je nižší verze, ve které token ohraničení chrání prostředek. Nesprávná verze tokenu pro ohraničení požadavku Další informace najdete v tématu [Správa verzí a hybridní logické hodiny]. (#versioning-a-hybrid-logical-clocks)
došlo k překročení kvóty. Úložiště stavů má kvótu počtu klíčů, které může uložit, což je založené na profilu paměti zadaného zprostředkovatele MQTT.
Chyba syntaxe Odeslaná datová část neodpovídá definici úložiště stavů.
neautorizuje Chyba autorizace
neznámý příkaz Příkaz není rozpoznán.
nesprávný počet argumentů Nesprávný počet očekávaných argumentů
chybějící časové razítko Když klienti dělají sadu, musí nastavit vlastnost uživatele MQTT5 __ts jako HLC představující časové razítko.
chybné časové razítko Časové razítko v __ts nebo token pro šermování není legální.
délka klíče je nula. Klíče nesmí být nulové délky v úložišti stavů.

Správa verzí a hybridní logické hodiny

Tato část popisuje, jak úložiště stavů zpracovává správu verzí.

Verze jako hybridní logické hodiny

Úložiště stavů udržuje verzi pro každou hodnotu, kterou ukládá. Úložiště stavů může k údržbě verzí použít monotonicky rostoucí čítač. Místo toho úložiště stavů používá hybridní logické hodiny (HLC) k reprezentaci verzí. Další informace najdete v článcích o původním návrhu HLC a záměru za hlc.

Úložiště stavů používá k definování HLC následující formát:

{wallClock}:{counter}:{node-Id}

Jedná se wallClock o počet milisekund od epochy Unixu. counter a node-Id obecně fungují jako HLC.

Když klienti dělají SET, musí nastavit vlastnost __ts uživatele MQTT5 jako HLC představující časové razítko na základě aktuálních hodin klienta. Úložiště stavů vrátí verzi hodnoty ve zprávě odpovědi. Odpověď je také určena jako HLC a také používá __ts vlastnost uživatele MQTT5. Vrácený HLC je vždy větší než HLC počátečního požadavku.

Příklad nastavení a načtení verze hodnoty

Tato část ukazuje příklad nastavení a získání verze pro hodnotu.

Klientská sada keyName=value. Hodiny klienta jsou 3. října 11:07:05 GMT. Hodnota hodin je 1696374425000 milisekund od epochy unixu. Předpokládejme, že systémové hodiny úložiště stavů jsou stejné jako systémové hodiny klienta. Klient provede SET příkaz, jak je popsáno výše.

Následující diagram znázorňuje SET příkaz:

Diagram příkazu úložiště stavu pro nastavení verze pro hodnotu

Vlastnost __ts (timestamp) v počáteční sadě obsahuje 1696374425000 jako hodiny klienta, čítač jako 0a id uzlu jako CLIENT. V odpovědi vlastnost, __ts kterou úložiště stavů vrátí obsahuje wallClock, čítač se zvýší o jeden a id uzlu jako StateStore. Úložiště stavů by mohlo vrátit vyšší wallClock hodnotu, pokud by jeho hodiny byly dopředu na základě toho, jak HLC funguje.

Tato verze se vrátí také u úspěšných GETDELa VDEL požadavků. V těchto požadavcích klient nezadá __ts.

Následující diagram znázorňuje GET příkaz:

Diagram úložiště stavů získání verze hodnoty

Poznámka:

Časové razítko __ts , které vrátí úložiště stavů, je stejné jako to, co vrátilo v počátečním SET požadavku.

Pokud se daný klíč později aktualizuje o nový SET, proces je podobný. Klient by měl nastavit svůj požadavek __ts na základě aktuálních hodin. Úložiště stavů aktualizuje verzi hodnoty a vrátí následující __tspravidla aktualizace HLC.

Časový posun

Úložiště stavů odmítne __ts (a také __ft) více než minutu před místním časem úložiště stavů.

Úložiště stavů přijímá __ts místní hodiny úložiště stavů. Jak je uvedeno v algoritmu HLC, úložiště stavů nastaví verzi klíče na místní hodiny, protože je větší.

Uzamykání a uzamykání tokenů

Tato část popisuje účel a použití uzamykání a tokenů ohraničení.

Pozadí

Předpokládejme, že existují dva nebo více klientů MQTT, kteří používají úložiště stavů. Oba klienti chtějí zapisovat do daného klíče. Klienti úložiště stavů potřebují mechanismus pro uzamčení klíče tak, aby daný klíč mohl upravovat pouze jeden klient najednou.

Příkladem tohoto scénáře jsou aktivní a pohotovostní systémy. Mohou existovat dva klienti, kteří provádějí stejnou operaci a operace může obsahovat stejnou sadu klíčů úložiště stavu. V daném okamžiku je jeden z klientů aktivní a druhý stojí, aby okamžitě převzal, pokud aktivní systém přestane reagovat nebo se chybově ukončí. V ideálním případě by do úložiště stavů v daném okamžiku měl zapisovat pouze jeden klient. V distribuovaných systémech je ale možné, že se oba klienti chovají, jako by byli aktivní, a zároveň se pokusí zapisovat do stejných klíčů. Tento scénář vytvoří podmínku časování.

Úložiště stavů poskytuje mechanismy, které brání tomuto stavu časování pomocí tokenů ohraničení. Další informace o tokenech šermování a třídě podmínek časování, které jsou navrženy pro ochranu proti, najdete v tomto článku.

Získání tokenu pro šerming

Tento příklad předpokládá, že máme následující prvky:

  • Client1 a Client2. Tito klienti jsou klienti úložiště stavu, kteří fungují jako aktivní a pohotovostní pár.
  • LockName. Název klíče v úložišti stavů, který funguje jako zámek.
  • ProtectedKey. Klíč, který je potřeba chránit před více zapisovači.

Klienti se pokusí získat zámek jako první krok. Dostanou zámek tím, že SET LockName {CLIENT-NAME} NEX PX {TIMEOUT-IN-MILLISECONDS}dělají . Vzpomeňte si z nastavení možností , že NEX příznak znamená, že SET úspěch proběhne pouze v případě splnění jedné z následujících podmínek:

  • Klíč byl prázdný.
  • Hodnota klíče je již nastavena na <hodnotu> a PX určuje časový limit v milisekundách.

Předpokládejme, že Client1 jde nejprve s žádostí o SET LockName Client1 NEX PX 10000. Tato žádost jí dává vlastnictví LockName 10 000 milisekund. Pokud Client2 se pokusí o SET LockName Client2 NEX ... chvíli Client1 vlastníkem zámku, příznak znamená, NEX že Client2 požadavek selže. Client1 tento zámek je potřeba obnovit odesláním stejného SET příkazu použitého k získání zámku, pokud Client1 chcete pokračovat ve vlastnictví.

Poznámka:

A SET NX je koncepčně ekvivalentní .AcquireLock()

Použití tokenů pro fencing u požadavků SET

Při Client1 úspěšném provedení SET operace ("AcquireLock") vrátí LockNameúložiště stavů verzi LockName jako hybridní logické hodiny (HLC) ve vlastnosti __tsuživatele MQTT5 .

Když klient provede SET požadavek, může volitelně zahrnout vlastnost __ft uživatele MQTT5, která představuje token pro dělení. Tato __ft hodnota je reprezentována jako HLC. Token ohraničení přidružený k danému páru klíč-hodnota poskytuje kontrolu vlastnictví zámku. Token šermování může pocházet odkudkoli. Pro tento scénář by měla pocházet z verze LockName.

Následující diagram znázorňuje proces Client1 provedení SET požadavku LockNamena:

Diagram klienta, který provádí nastavený požadavek na vlastnost názvu zámku

Client1 Dále použije __ts vlastnost (Property=1696374425000:1:StateStore) nezměněnou jako základ __ft vlastnosti v požadavku k úpravě ProtectedKey. Stejně jako všechny SET požadavky musí klient nastavit __ts vlastnost ProtectedKey.

Následující diagram znázorňuje proces Client1 provedení SET požadavku ProtectedKeyna:

Diagram klienta, který provádí nastavený požadavek na vlastnost chráněného klíče

Pokud je požadavek úspěšný, od tohoto okamžiku ProtectedKey vyžaduje token pro ohraničení, který je roven nebo větší než token zadaný v SET požadavku.

Algoritmus tokenů pro fencing

Úložiště stavů přijímá všechny HLC pro __ts pár klíč-hodnota, pokud je hodnota v maximálním šikmém formátu. To samé ale neplatí pro tokeny šermování.

Algoritmus úložiště stavů pro tokeny ohraničení je následující:

  • Pokud pár klíč-hodnota nemá přidružený token pro ohraničení a SET sada __ftpožadavků, úložiště stavů ukládá přidružené __ft k páru klíč-hodnota.
  • Pokud má pár klíč-hodnota přidružený token pro ohraničení:
    • SET Pokud požadavek neurčil__ft, zamítněte žádost.
    • SET Pokud požadavek zadal __ft starší hodnotu HLC, než je token pro ohraničení přidružený ke dvojici klíč-hodnota, zamítněte požadavek.
    • SET Pokud požadavek zadal __ft hodnotu HLC, která má stejnou nebo novější hodnotu HLC, než je token pro ohraničení přidružený ke dvojici klíč-hodnota, přijměte požadavek. Úložiště stavů aktualizuje token ohraničení páru klíč-hodnota tak, aby byl nastavený v požadavku, pokud je novější.

Jakmile je klíč označen tokenem pro ohraničení, požadavek bude úspěšný DEL a VDEL požadavky také vyžadují __ft , aby byla vlastnost zahrnuta. Algoritmus je shodný s předchozím tokenem s tím rozdílem, že token pro ohraničení není uložený, protože klíč se odstraňuje.

Chování klienta

Tyto mechanismy uzamykání spoléhají na to, že se klienti dobře chovají. V předchozím příkladu nebylo možné chybné chování Client2 vlastnit LockName a přesto úspěšně provést SET ProtectedKey výběr tokenu šermingu, který je novější než ProtectedKey token. Úložiště stavů si to neuvědomuje LockName a ProtectedKey nemá žádný vztah. V důsledku toho úložiště stavů neprovádí ověření, které Client2 skutečně vlastní hodnotu.

Klienti můžou psát klíče, pro které zámek ve skutečnosti nevlastní, je nežádoucí chování. Můžete chránit před takovým nesprávným chováním klienta tím, že správně implementujete klienty a pomocí ověřování omezíte přístup ke klíčům jenom důvěryhodným klientům.

Oznámení

Klienti se můžou zaregistrovat v úložišti stavů, aby dostávali oznámení o změněných klíčů. Představte si scénář, ve kterém termostat používá klíč {thermostatName}\setPointúložiště stavu . Ostatní klienti úložiště stavů mohou změnit hodnotu tohoto klíče a změnit nastavení termostatu. Místo dotazování na změny se termostat může zaregistrovat v úložišti stavů pro příjem zpráv při {thermostatName}\setPoint úpravě.

KEYNOTIFY – zprávy žádosti

Klienti úložiště stavu požadují, aby úložiště stavu monitoruje dané keyName změny odesláním KEYNOTIFY zprávy. Stejně jako všechny žádosti o úložiště stavů klienti publikují zprávu QoS1 s touto zprávou prostřednictvím MQTT5 do tématu statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/command/invokesystému úložiště stavů .

Datová část požadavku má následující formulář:

KEYNOTIFY<CR><LF>
{keyName}<CR><LF>
{optionalFields}<CR><LF>

Kde:

  • KEYNOTIFY je řetězcový literál určující příkaz.
  • {keyName} je název klíče pro naslouchání oznámením. Zástupné dokumentace se v současné době nepodporují.
  • {optionalFields} Aktuálně podporované volitelné hodnoty polí jsou:
    • {STOP} Pokud existuje oznámení se stejným keyName a clientId jako tento požadavek, úložiště stavů ho odebere.

Následující příklad výstupu KEYNOTIFY ukazuje požadavek na monitorování klíče SOMEKEY:

*2<CR><LF>
$9<CR><LF>
KEYNOTIFY<CR><LF>
$7<CR><LF>
SOMEKEY<CR><LF>

Zpráva odpovědi KEYNOTIFY

Stejně jako všechny požadavky RPC úložiště stavu vrátí úložiště stavu svou odpověď na Response Topic a používá Correlation Data vlastnosti zadané z počátečního požadavku. Úspěšná KEYNOTIFYodpověď značí, že úložiště stavu žádost zpracovalo. Jakmile úložiště stavu požadavek úspěšně zpracuje, buď monitoruje klíč aktuálního klienta, nebo zastaví monitorování.

V případě úspěchu je odpověď úložiště stavů stejná jako úspěšná SETodpověď .

+OK<CR><LF>

Pokud klient odešle KEYNOTIFY SOMEKEY STOP požadavek, ale úložiště stavů tento klíč nesměruje, odpověď úložiště stavů je stejná jako při pokusu o odstranění klíče, který neexistuje.

:0<CR><LF>

Jakékoli jiné selhání se řídí obecným vzorem zasílání zpráv o chybách úložiště stavů:

-ERR: <DESCRIPTION OF ERROR><CR><LF>

Témata a životní cyklus oznámení KEYNOTIFY

keyName Při úpravě nebo odstranění monitorovaného prostřednictvím KEYNOTIFY úložiště stavu odešle klientovi oznámení. Téma je určeno konvencí – klient během procesu nezadá téma KEYNOTIFY .

Téma je definováno v následujícím příkladu. Jedná se clientId o šestnáctkové znázornění id klienta MQTT ClientId klienta, který inicioval KEYNOTIFY požadavek, a keyName představuje šestnáctkové zakódované vyjádření klíče, který se změnil. Úložiště stavů se řídí pravidly kódování RFC 4648 – Base16, Base32 a Base64 Pro toto kódování.

clients/statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/{clientId}/command/notify/{keyName}

Například zprostředkovatel MQTT publikuje NOTIFY zprávu odeslanou client-id1 s upraveným názvem SOMEKEY klíče do tématu:

clients/statestore/v1/FA9AE35F-2F64-47CD-9BFF-08E2B32A0FE8/636C69656E742D696431/command/notify/534F4D454B4559`

Klient, který používá oznámení, by měl SUBSCRIBE toto téma obsahovat a čekat SUBACK na přijetí před odesláním jakýchkoli KEYNOTIFY požadavků, aby se neztratily žádné zprávy.

Pokud se klient odpojí, musí se znovu připsat k KEYNOTIFY tématu oznámení a znovu odeslat KEYNOTIFY příkaz pro všechny klíče, které potřebuje k dalšímu monitorování. Na rozdíl od předplatných MQTT, která je možné zachovat v nečisté relaci, úložiště stavů interně odebere všechny KEYNOTIFY zprávy, když se daný klient odpojí.

Formát zprávy oznámení KEYNOTIFY

Při úpravě klíče monitorovaného prostřednictvím KEYNOTIFY úložiště stavu se v úložišti stavů zobrazí PUBLISH zpráva s tématem oznámení podle formátu pro uložení stavu klientů registrovaných ke změně.

NOTIFY<CR><LF>
{operation}<CR><LF>
{optionalFields}<CR><LF>

Do zprávy jsou zahrnuty následující podrobnosti:

  • NOTIFY je řetězcový literál zahrnutý jako první argument v datové části, který označuje doručené oznámení.
  • {operation} je událost, ke které došlo. V současné době jsou tyto operace:
    • SET hodnota byla změněna. K této operaci může dojít pouze v důsledku SET příkazu z klienta úložiště stavu.
    • DEL hodnota byla odstraněna. K této operaci může dojít kvůli DEL klientovi úložiště stavu nebo VDEL příkazu.
  • optionalFields
    • VALUE a {MODIFIED-VALUE}. VALUE je řetězcový literál označující, že další pole {MODIFIED-VALUE}, obsahuje hodnotu, na kterou byl klíč změněn. Tato hodnota se odesílá pouze v odpovědi na klíče, které se mění z důvodu SET.

Následující příklad výstupu ukazuje zprávu s oznámením odeslanou při změně klíče SOMEKEY na hodnotu abc, včetně VALUE , protože počáteční požadavek určil GET možnost:

*4<CR><LF>
$6<CR><LF>
NOTIFY<CR><LF>
$3<CR><LF>
SET<CR><LF>
$5<CR><LF>
VALUE<CR><LF>
$3<CR><LF>
abc<CR><LF>

Zpráva KEYNOTIFY s oznámením obsahuje časové razítko hodnoty při upozorňování klienta na požadavek SET (aktualizace hodnoty) nebo při upozorňování klienta na požadavek DEL nebo VDEL (hodnota odstraněna). Časové razítko je součástí uživatelského __ts zprávy MQTT v5. Další informace najdete v části Verze jako hybridní logické hodiny.