A lecke végére meg tudod tervezni egy WebSocket-kapcsolat üzenetborítékát, meg tudod különböztetni a kérést, a választ és az eseményt, és fel tudod sorolni, milyen azonosítók és nyugták kellenek a megbízható működéshez.
Miért kell?
A send(JSON.stringify(adat)) csak a továbbítás technikája; a fogadó ettől még nem tudja, milyen műveletet kell végeznie, és a küldő sem tudja, sikerült-e. A WebSocket nem definiálja, mi a „belépés” vagy a „feliratkozás” (10.1). Egy működő rendszernek üzenettípusokat, válaszokat, hibákat és sorrendi szabályokat kell megállapítania, vagyis alkalmazási protokollt.
Üzenetboríték
Hasznos egy következetes boríték, amely minden üzenetnél ugyanazokat a mezőket adja:
version: az üzenetformátum változata (nem az üzleti állapot verziója);
type: az üzenet jelentése;
requestId: a kérés és a válasz összepárosítására;
eventId: a szerveroldali tény egyedi azonosítója;
payload: a tényleges tartalom.
A borítékot a WebSocket handshake-ben egyeztetett alprotokoll (10.1) is megnevezheti. Az üzenetazonosítót, az üzleti műveletazonosítót (idempotenciakulcs, 6.5) és a trace-azonosítót (10.5) külön kell tartani; egyik sem helyettesíti a másikat.
Kérés, válasz, esemény
Három kategória van: a kliens által indított kérés, az erre adott eredmény, és a szerver által kezdeményezett esemény. A típusmező különbözteti meg őket. A feliratkozás elfogadása nem azonos a korábbi események kézbesítésével; a szerződés jelölheti külön a visszajátszás végét és az élő folyam kezdetét. Ha az indulás állapotból történik, meg kell határozni a pillanatkép és az utána következő események közös verzióhatárát (10.3).
Hibák és érvénytelen üzenetek
Ismeretlen típus, hibás JSON, túl nagy üzenet és nem megengedett művelet esetén stabil hibakód szükséges. Nem minden hiba indokolja a kapcsolat bontását: hibás kérésre válasz adható, ismételt szabálysértés vagy protokoll-inkompatibilitás esetén viszont indokolt lehet lezárni. A sémát a szerver is ellenőrzi; a kliensoldali validáció és a típusrendszer nem bizonyítja a beérkező adat helyességét, és a felhasználóazonosító sem tekinthető hitelesnek csak azért, mert JSON-mezőként érkezett.
Nyugták jelentése
A „megérkezett”, az „elfogadtuk” és a „végrehajtottuk” eltérő nyugta (8.2). Hosszú műveletnél a szerver először feladatazonosítót adhat, majd később küld eredményt. Ha a művelet tartós üzleti jelentőségű, a kliensnek kapcsolatvesztés után más úton is le kell tudnia kérdezni az állapotot. Ha a kliens nem kap végleges eredményt, az ismétlésnek ugyanahhoz a logikai művelethez kell kapcsolódnia: új requestId önmagában új parancsnak látszhat; külön idempotenciakulcs vagy dokumentált újrafelhasználási szabály kell.
Sorrend és párhuzamos feldolgozás
Egy kapcsolaton a keretek sorrendje rendezett (a Socket.IO dokumentációja is megkülönbözteti, hogy ennek a sorrendnek a garanciáját a szállítástól függetlenül adja), de a szerver külön feladatokban indított műveletei eltérő sorrendben fejeződhetnek be. A válaszokat ezért azonosítóval kell párosítani, nem azzal, hogy „az első válasz az első kéréshez tartozik”. Több kapcsolat vagy szerverpéldány között külön sorrendi szerződés kell (8.3). Az üzenetverzió és az entitásverzió más jelentésű: az első a formátumot, a második az üzleti állapot előrehaladását jelzi.
Jellemzők
Szempont
WebSocket-üzenetváltás
Irány
Kétirányú
Kezdeményező
Mindkét fél
Kapcsolat tartóssága
Tartós
Késleltetés
Alacsony; a feldolgozás a szerver oldali munkától függ
Terhelés
Az üzenetek száma és a szerveroldali munka költsége
Hibatűrés
Azonosítók, nyugták, idempotencia a szerződés része
Mikor jó?
Ha a kérés–válasz és az események ugyanazon a csatornán, alacsony késleltetéssel kellenek
Mikor nem?
Ha a tartós üzleti eredményt a csatorna megszakadása veszélyeztetné és nincs lekérdezési út
Gyakori tévhitek
Állítás
Pontosítás
„A JSON-üzenet elég protokoll.”
Típus, azonosító, hiba- és nyugtaszabály is kell.
„A kapcsolaton az első válasz az első kéréshez tartozik.”
A műveletek eltérő sorrendben végződhetnek; azonosítóval kell párosítani.
„Új requestId = ugyanaz a művelet.”
Új parancsnak látszhat; idempotenciakulcs kell.
„A kliens validációja elég.”
A szervernek is ellenőriznie kell.
Röviden
A WebSocketre alkalmazási protokoll kell: típus, azonosítók, hibakódok, nyugták.
A boríték: version, type, requestId/eventId, payload.
A „megérkezett”, „elfogadtuk” és „végrehajtottuk” külön nyugta.
A válaszokat azonosítóval kell párosítani; a tartós műveletnek legyen lekérdezhető állapota.
Ellenőrző kérdések
Miért nem elég a JSON.stringify mint protokoll?
Miben különbözik az üzenetverzió az entitásverziótól?
Hogyan kell ismételni egy kérést, ha nem érkezett végleges eredmény?
WebSocket fölötti alkalmazási protokoll
Célok
A lecke végére meg tudod tervezni egy WebSocket-kapcsolat üzenetborítékát, meg tudod különböztetni a kérést, a választ és az eseményt, és fel tudod sorolni, milyen azonosítók és nyugták kellenek a megbízható működéshez.
Miért kell?
A
send(JSON.stringify(adat))csak a továbbítás technikája; a fogadó ettől még nem tudja, milyen műveletet kell végeznie, és a küldő sem tudja, sikerült-e. A WebSocket nem definiálja, mi a „belépés” vagy a „feliratkozás” (10.1). Egy működő rendszernek üzenettípusokat, válaszokat, hibákat és sorrendi szabályokat kell megállapítania, vagyis alkalmazási protokollt.Üzenetboríték
Hasznos egy következetes boríték, amely minden üzenetnél ugyanazokat a mezőket adja:
{ "version": 1, "type": "subscribe", "requestId": "req-31", "payload": { "channel": "orders", "afterEventId": "evt-90" } }version: az üzenetformátum változata (nem az üzleti állapot verziója);type: az üzenet jelentése;requestId: a kérés és a válasz összepárosítására;eventId: a szerveroldali tény egyedi azonosítója;payload: a tényleges tartalom.A borítékot a WebSocket handshake-ben egyeztetett alprotokoll (10.1) is megnevezheti. Az üzenetazonosítót, az üzleti műveletazonosítót (idempotenciakulcs, 6.5) és a trace-azonosítót (10.5) külön kell tartani; egyik sem helyettesíti a másikat.
Kérés, válasz, esemény
Három kategória van: a kliens által indított kérés, az erre adott eredmény, és a szerver által kezdeményezett esemény. A típusmező különbözteti meg őket. A feliratkozás elfogadása nem azonos a korábbi események kézbesítésével; a szerződés jelölheti külön a visszajátszás végét és az élő folyam kezdetét. Ha az indulás állapotból történik, meg kell határozni a pillanatkép és az utána következő események közös verzióhatárát (10.3).
Hibák és érvénytelen üzenetek
Ismeretlen típus, hibás JSON, túl nagy üzenet és nem megengedett művelet esetén stabil hibakód szükséges. Nem minden hiba indokolja a kapcsolat bontását: hibás kérésre válasz adható, ismételt szabálysértés vagy protokoll-inkompatibilitás esetén viszont indokolt lehet lezárni. A sémát a szerver is ellenőrzi; a kliensoldali validáció és a típusrendszer nem bizonyítja a beérkező adat helyességét, és a felhasználóazonosító sem tekinthető hitelesnek csak azért, mert JSON-mezőként érkezett.
Nyugták jelentése
A „megérkezett”, az „elfogadtuk” és a „végrehajtottuk” eltérő nyugta (8.2). Hosszú műveletnél a szerver először feladatazonosítót adhat, majd később küld eredményt. Ha a művelet tartós üzleti jelentőségű, a kliensnek kapcsolatvesztés után más úton is le kell tudnia kérdezni az állapotot. Ha a kliens nem kap végleges eredményt, az ismétlésnek ugyanahhoz a logikai művelethez kell kapcsolódnia: új
requestIdönmagában új parancsnak látszhat; külön idempotenciakulcs vagy dokumentált újrafelhasználási szabály kell.Sorrend és párhuzamos feldolgozás
Egy kapcsolaton a keretek sorrendje rendezett (a Socket.IO dokumentációja is megkülönbözteti, hogy ennek a sorrendnek a garanciáját a szállítástól függetlenül adja), de a szerver külön feladatokban indított műveletei eltérő sorrendben fejeződhetnek be. A válaszokat ezért azonosítóval kell párosítani, nem azzal, hogy „az első válasz az első kéréshez tartozik”. Több kapcsolat vagy szerverpéldány között külön sorrendi szerződés kell (8.3). Az üzenetverzió és az entitásverzió más jelentésű: az első a formátumot, a második az üzleti állapot előrehaladását jelzi.
Jellemzők
Gyakori tévhitek
Röviden
version,type,requestId/eventId,payload.Ellenőrző kérdések
JSON.stringifymint protokoll?Források