• No results found

Struktura pˇr´ıkazu pro nastaven´ı priority uzlu

uzkou souvislost s ˇrazen´ım jednotliv´ych pˇr´ıkaz˚u do front, jeˇz bude pops´ano na stranˇe 97.

Struktura pˇr´ıkazu Node Priority je uvedena na obr´azku 5.15. Priorita uzlu m˚uˇze nab´yvat hodnot v rozsahu h0, 255i, kde 0 znaˇc´ı nejniˇzˇs´ı prioritu a hodnota 255 nejvyˇsˇs´ı prioritu. Obecnˇe lze ˇr´ıci, ˇze ˇc´ım vˇetˇs´ı m´a uzel prioritu, t´ım vˇetˇs´ı ˇsanci na pˇrenesen´ı maj´ı data v dan´em uzlu.

0 1 1 2 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +---+---+---+---+

| OpCode=43 | Length=7 | Node ID (high) |

+---+---+---+---+

| Node ID (low) | Priority |

+---+---+---+

Obr´azek 5.15: Struktura pˇr´ıkazu pro nastaven´ı priority uzlu

Pˇri odesl´an´ı pˇr´ıkazu Node Priority si tuto prioritu mus´ı u sebe nastavit i klient. Priority uzl˚u se nastavuj´ı ve stromov´e struktuˇre rekurzivnˇe. Je d˚uleˇzit´e si uvˇedomit, ˇze priority uzl˚u jsou na kaˇzd´em spojen´ı r˚uzn´e a klient mus´ı m´ıt moˇznost nastavit si prioritu i pro uzly, kter´e m˚uˇze pouze ˇc´ıst.

Obr´azek 5.16: Sch´ema moˇzn´eho uspoˇr´ad´an´ı objekt˚u do oktanov´eho stromu Rychl´y pohyb Avatara rozs´ahlou 3D sc´enou m˚uˇze v´ezt k tomu, ˇze kli-ent bude m´ıt potˇrebu ˇcasto mˇenit prioritu u vˇetˇsiny uzl˚u. Poˇzadavky na zmˇenu priorit uzl˚u by potom mohly spotˇrebovat velkou ˇc´ast ˇs´ıˇrky p´asma.

Z toho d˚uvodu je vhodn´e omezit mnoˇzstv´ı odes´ılan´ych pˇr´ıkaz˚u Node priority tak, aby vyuˇz´ıvaly jenom urˇcitou ˇc´ast ˇs´ıˇrky p´asma. D´ale je vhodn´e objekty ukl´adat do list˚u bin´arn´ıho nebo oktanov´eho stromu, aby se mohlo efektivnˇe vyuˇz´ıvat rekurzivn´ıho nastavov´an´ı priorit uzl˚u. Zjednoduˇsen´y pˇr´ıklad uloˇzen´ı objekt˚u do oktanov´eho stromu je uveden na obr´azku 5.16. V tomto zjed-noduˇsen´em pˇr´ıkladu byly priority nastaveny pouze u uzl˚u, jeˇz jsou potomky koˇrenov´eho uzlu. Z pˇr´ıkladu je nav´ıc patrn´e, ˇze nen´ı nutn´e pˇren´aˇset ke kli-entovi objekty nach´azej´ıc´ı se mimo zorn´y ´uhel avatara. Uzl˚um, kter´e jsou napˇr´ıklad mimo zorn´y ´uhel nebo jsou od avatara pˇr´ıliˇs daleko, by mˇel kli-ent pˇriˇrazovat priorita menˇs´ı jak 128. Informace o tˇechto uzlech jsou totiˇz odesl´any teprve, kdyˇz jsou odesl´any informace pro uzly s prioritou vyˇsˇs´ı jak 127. Dalˇs´ı informace t´ykaj´ıc´ı se pl´anov´an´ı pˇr´ıkaz˚u na z´akladˇe priorit jsou uvedeny v kapitole 6.3 na stranˇe 97.

V´ychoz´ı hodnota priority novˇe vytvoˇren´ych uzl˚u by mˇela b´yt nastavena na hodnotu 127.

Dalˇs´ıho vylepˇsen´ı pˇri optim´aln´ım stanoven´ı priorit uzl˚u m˚uˇze b´yt dosaˇzeno za pouˇzit´ı Kalmanova filtru, jak bylo pops´ano v [23]. Pro stanoven´ı priorit v MMORPG lze pouˇz´ıt algoritmy popsan´e v [7].

5.2.12 Tagy a skupiny tag˚ u

Tagy a skupiny tag˚u jsou pˇr´ıtomny i v p˚uvodn´ı verzi protokolu. Umoˇzˇnuj´ı do uzl˚u ukl´adat jednak dodateˇcn´e informace jako napˇr´ıklad textov´e pozn´amky, skuteˇcn´e jm´eno autora, datum posledn´ı zmˇeny, apod. Tagy a skupiny tag˚u z´aroveˇn umoˇzˇnuj´ı do uzl˚u ukl´adat i dalˇs´ı uˇziteˇcn´e informace jako je hmotnost objektu, teplota, atd.

Koncept nov´eho datov´eho modelu poˇc´ıt´a s t´ım, ˇze spousta specializo-van´ych typ˚u objekt˚u je nahrazena jedn´ım obecn´ym typem uzl˚u. V´yznam jednotliv´ych uzl˚u by mˇel b´yt pops´an pr´avˇe pomoc´ı tag˚u. Z´aroveˇn byly tagy uzp˚usobeny k efektivn´ımu ukl´ad´an´ı uˇziteˇcn´ych informac´ı. ˇCasto mˇenit infor-mace v tagech je nyn´ı stejnˇe efektivn´ı jako mˇenit je ve vrstv´ach.

Kaˇzd´y objekt m˚uˇze tedy obsahovat tagy, kter´e maj´ı (v r´amci sv´e skupiny) sv´e jedineˇcn´e jm´eno, jedineˇcn´y ˇc´ıseln´y identifik´ator, typ a hodnotu. Tagy nav´ıc mus´ı b´yt uspoˇr´ad´any do skupin tag˚u jeˇz maj´ı (v r´amci objektu) sv´e jedineˇcn´e jm´eno a identifik´ator.

Tag m˚uˇze m´ıt vˇzdy jeden z n´asleduj´ıc´ıch typ˚u:

• int8 (signed char)

• uint8 (unsigned char)

• int16 (signed short)

• uint16 (unsigned short)

• int32 (signed int)

• uint32 (unsigned int)

• real32 (float)

• real64 (double)

• string8 (unsigned char, *char)

Jm´ena tag˚u i skupiny tag˚u mohou b´yt dlouh´a pouze 255 znak˚u. Pˇr´ıklad struktury vytvoˇren´e ze skupin tag˚u a vlastn´ıch tag˚u m˚uˇze m´ıt n´asleduj´ıc´ı podobu:

• TagGroup(name: Asset, ID: 0)

– Tag(name: Name, ID: 0, type: string8, value: Obj.001) – Tag(name: Author, ID: 1, type: string8, value: Jan Nov´y) – Tag(name: Version, ID: 2, type: uint8, value: 5)

– Tag(name: Subversion, ID: 3, type: uint8, value: 3)

• TagGroup(name: Transformation, ID: 1)

– Tag(name: PosX, ID: 0, type: real32, value: 10.23) – Tag(name: PosY, ID: 1, type: real32, value: 7.68) – Tag(name: PosZ, ID: 2, type: real32, value: -0.03) – Tag(name: QuatW, ID: 3, type: real32, value: 1.77) – Tag(name: QuatX, ID: 4, type: real32, value: -3.2) – Tag(name: QuatY, ID: 5, type: real32, value: -7.04) – Tag(name: QuatZ, ID: 6, type: real32, value: 0.0) – Tag(name: ScaleX, ID: 7, type: real32, value: 1.0) – Tag(name: ScaleY, ID: 8, type: real32, value: 2.0) – Tag(name: ScaleZ, ID: 9, type: real32, value: 1.0)

Skupiny tag˚u i samotn´e tagy obsahuj´ı kromˇe jedineˇcn´eho jm´ena i je-dineˇcn´y ˇc´ıseln´y identifik´ator z toho d˚uvodu, ˇze se n´aslednˇe zjednoduˇsuj´ı pˇr´ıkazy odkazuj´ıc´ı se na dan´e skupiny tag˚u a tagy. ˇRetˇezec by ve vˇetˇsinˇe pˇr´ıpad˚u v pˇr´ıkazu zab´ıral v´ıce m´ısta jak dvou bytov´e ID.

Skupiny tag˚u

Skupinu tag˚u lze vytvoˇrit pomoc´ı pˇr´ıkazu TagGroup Create jehoˇz struk-tura je uvedena v pˇr´ıloze na obr´azku 10.13 na stranˇe 153. Souˇc´ast´ı tohoto pˇr´ıkazu je v r´amci objektu jedineˇcn´y ˇc´ıseln´y identifik´ator skupiny a jm´eno skupiny. Pˇr´ıkazy TagGroup Create by mˇel server poslat klientovi pro vˇsechny skupiny tag˚u v objektu, kdyˇz se k tomuto objektu pˇrihl´as´ı pomoc´ı pˇr´ıkazu Node Subscribe.

Skupinu tag˚u vˇcetnˇe vˇsech tag˚u uvnitˇr t´eto skupiny lze zruˇsit pomoc´ı pˇr´ıkazu TagGroup Destroy jeˇz je uveden v pˇr´ıloze na obr´azku 10.14 na stranˇe 153. Skupinu tag˚u m˚uˇze zruˇsit kaˇzd´y uˇzivatel, kter´y m´a pr´avo do dan´eho uzlu zapisovat.

Jm´ena skupin a jejich v´yznam by mˇely b´yt definovan´y v DED. Klient se potom m˚uˇze na z´akladˇe jm´ena skupiny tag˚u rozhodnout, jestli obsahu dan´e skupiny rozum´ı, pˇr´ıpadnˇe jestli ho dan´a skupina zaj´ım´a. V takov´em pˇr´ıpadˇe se m˚uˇze do skupiny tag˚u pˇrihl´asit pˇr´ıkazem TagGroup Subscribe jehoˇz struk-tura je uvedena v pˇr´ıloze na obr´azku 10.15 na stranˇe 153. Od skupiny tag˚u se lze odhl´asit pomoc´ı pˇr´ıkazu TagGroup Unsubscribe, jehoˇz struktura je uve-dena na obr´azku 10.16.

Tagy

Kdyˇz se klient pˇrihl´as´ı k nepr´azdn´e skupinˇe tag˚u, server mu poˇsle sadu pˇr´ıkaz˚u Tag Create pro vˇsechny tagy v dan´e skupinˇe. Struktura dan´eho pˇr´ıkazu je uvedena na obr´azku 5.17. Aby se klient nemusel pˇrihlaˇsovat ke kaˇzd´emu tagu zvl´aˇst’, tak je klient automaticky pˇrihl´aˇsen ke vˇsem tag˚um v dan´e skupinˇe. Server m˚uˇze poslat vlastn´ı hodnotu tagu v pˇr´ıkazu Tag Set teprve, aˇz obdrˇz´ı od klienta potvrzen´ı o doruˇcen´ı paketu s pˇr´ıkazem Tag Create.

0 1 1 2 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +---+---+---+---+

| OpCode=48 | Length | Node ID (high) |

+---+---+---+---+

| Node ID (low) | TagGroup ID |

+---+---+---+---+

| Tag ID | String Length | ... |

+---+---+---+---+

| ... | Type |

+---+---+---+---+

Obr´azek 5.17: Struktura pˇr´ıkazu pro vytvoˇren´ı nov´eho tagu

Tagy m˚uˇze pomoc´ı pˇr´ıkazu Tag Create vytv´aˇret i klient, ale poloˇzka Tag ID mus´ı b´yt nastavena na hodnotu 0xFFFF, protoˇze jedineˇcn´y identifik´ator

pro tag vyb´ır´a opˇet server. Klient mus´ı pˇr´ıkaz Tag Create pos´ılat s jedineˇcn´ym jm´enem. Kdyˇz server obdrˇz´ı pˇr´ıkaz Tag Create s jiˇz pouˇz´ıvan´ym jm´enem, tak tento pˇr´ıkaz zahod´ı, pˇr´ıpadnˇe m˚uˇze klientovi poslat pˇr´ıkaz s negativn´ım potvrzen´ım dan´e zpr´avy.

Obr´azek 5.18: Struktura pˇr´ıkazu pro nastaven´ı hodnoty tagu real32 Vlastn´ı hodnota tagu je pˇren´aˇsena v samostatn´em pˇr´ıkazu Tag Set, jenˇz se liˇs´ı podle typu tagu a zp˚usobu opakov´an´ı adresy pˇr´ıkazu. Pˇr´ıkaz pro nastaven´ı tagu real32 je uveden na obr´azku 5.18.

Kdyˇz se v jednom paketu vyskytuje mnoho pˇr´ıkaz˚u Tag Set, kter´e maj´ı totoˇznou znaˇcnou ˇc´ast adresy, tak by bylo neefektivn´ı tuto adresu opakovat.

Z tohoto d˚uvodu existuj´ı pro kaˇzd´y typ tagu 4 r˚uzn´e varianty pˇr´ıkazu Tag Set, jeˇz se liˇs´ı ve zp˚usobu opakov´an´ı jednotliv´ych poloˇzek adresy. Celkem je specifikov´ano 36 variant pˇr´ıkaz˚u Tag Set. Zp˚usoby opakov´an´ı pro typ real32 jsou uvedeny na obr´azku 5.19.

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Obr´azek 5.19: Jednotliv´e varianty opakov´an´ı adresy pˇr´ıkazu Tag Set (real32) Prvn´ı varianta (a) opakov´an´ı je totoˇzn´a se zp˚usobem opakov´an´ım u pˇred-choz´ıch pˇr´ıkaz˚u. To znamen´a, ˇze za poloˇzkami OpCode a Length se

opa-kuje vˇzdy cel´a adresa pˇr´ıkazu (Node ID, TagGroup ID a Tag ID ), kter´a je n´asledov´ana vlastn´ı hodnotou Value. Druh´a varianta (b) umoˇzˇnuje uv´est poloˇzku Node ID pouze jednou a u zbyl´ych adres uv´adˇet pouze TagGroup ID a Tag ID. Tˇret´ı varianta (c) umoˇzˇnuje sd´ılet i poloˇzku TagGroup ID.

Posledn´ı variantu (d) je moˇzn´e pouˇz´ıt v pˇr´ıpadˇe, ˇze odes´ılatel chce odeslat nˇekolik pˇr´ıkaz˚u Tag Set, jeˇz maj´ı stejn´y typ, stejn´e Node ID, TagGroup ID a Tag ID je u kaˇzd´eho n´asleduj´ıc´ıho pˇr´ıkazu inkrementov´ano o jedna.

Kaˇzd´a varianta je vhodn´a pro jin´e kombinace pˇr´ıkaz˚u a odes´ılatel by mˇel vˇzdy vybrat vhodnou metodu opakov´an´ı podle toho, jak´e m´a pˇr´ıkazy v odes´ılac´ı frontˇe. Kdyˇz budeme uvaˇzovat pˇr´ıklad ze strany 87, tak pˇri zmˇenˇe polohy, rotace ˇci velikosti objektu se nejl´epe hod´ı posledn´ı varianta (d) z obr´ a-zku 5.19. Zmˇena pozice z pˇr´ıkladu na stranˇe 87 lze pak efektivnˇe pˇren´est pomoc´ı pˇr´ıkazu, jenˇz je uveden´y na obr´azku 5.20.

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

|73| *| ** | *** |**** | 10.23 | 7.68 | -0.03 |

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

* - Length=22, ** - Node ID=65560, *** - TagGroup ID=1, **** - Tag ID=0

Obr´azek 5.20: Pˇr´ıklad komprese pˇr´ıkazu Tag Set, jeˇz byl pouˇzit´y pro pˇrenos pozice

5.2.13 Vrstvy

Vrstvy v nov´em protokolu umoˇzˇnuj´ı sd´ılet libovoln´a nestrukturovan´a data.

Jejich pˇr´ıkazy jsou navrˇzeny pro sd´ılen´ı objemn´ych dat, jako jsou napˇr´ıklad souˇradnice vertex˚u, vrcholy ploˇsek, v´ahy vertex˚u, apod. Struktura z´akladn´ıch pˇr´ıkaz˚u pro vytvoˇren´ı, zruˇsen´ı, pˇrihl´aˇsen´ı a odhl´aˇsen´ı se od vrstvy je uvedena v pˇr´ıloze na stranˇe 159. Kdyˇz se klient pˇrihl´as´ı k uzlu a ten obsahuje nˇejak´e vrstvy, tak obdrˇz´ı od serveru sadu pˇr´ıkaz˚u Layer Create obsahuj´ıc´ı identi-fik´atory a typy jednotliv´ych vrstev. V´yznam jednotliv´ych vrstev m˚uˇze b´yt d´an napˇr´ıklad ve skupinˇe tag˚u jak je uvedeno na n´asleduj´ıc´ım pˇr´ıkladu:

• TagGroup(name: Vertexes, ID: 0)

– Tag(name: LayerID, ID: 0, type: uint16, value: 0) – Tag(name: Components, ID: 1, type: uint8, value: 3)

Skupina tag˚u se jmenuje v tomto pˇr´ıkladu ”Vertexes”, coˇz znaˇc´ı, ˇze tato skupina bude obsahovat informace o vertexech. Tag s Tag ID=0 se jm´enem

”LayerID” m´a hodnotu 0, takˇze vertexy by mˇely b´yt obsaˇzeny v nult´e vrstvˇe.

Tag s Tag ID=1 je pojmenovan´y ”Components” a jeho hodnota je 3, tud´ıˇz kaˇzd´y vertex m´a vˇzdy tˇri sloˇzky.

Vrstvy mohou obsahovat vˇzdy pouze hodnoty jednoho typu. Podporovan´e typy jsou uvedeny na n´asleduj´ıc´ım seznamu:

• int8 (signed char)

• uint8 (unsigned char)

• int16 (signed short)

• uint16 (unsigned short)

• int32 (signed int)

• uint32 (unsigned int)

• real32 (float)

• real64 (double)

Kdyˇz se klient pˇrihl´as´ı k vybran´e vrstvˇe, tak mu server zaˇcne pos´ılat pˇr´ısluˇsn´e pˇr´ıkazy Item Create, kter´ych je definov´ano celkem 32. Opˇet se liˇs´ı podle typu pˇren´aˇsen´ych dat a zp˚usobu opakov´an´ı jednotliv´ych poloˇzek po-dobnˇe jak to bylo uvedeno na obr´azku 5.19.

Obr´azek 5.21: Porovn´an´ı efektivity vyuˇzit´ı m´ısta v p˚uvodn´ım (a) a nov´em protokolu (b)

Vrstvy mohou b´yt pouˇzity napˇr´ıklad pro sd´ılen´ı v´ahy vertex˚u. V´ahu ver-tex˚u m˚uˇze uˇzivatel v grafick´ych aplikac´ıch ovlivˇnovat pomoc´ı interaktivn´ıch n´astroj˚u jako je napˇr´ıklad ˇstˇetec. Pˇri kreslen´ı na v´ahu vertex˚u Verse klient generuje velk´e mnoˇzstv´ı pˇr´ıkaz˚u mˇen´ıc´ı v´ahu vertex˚u. Na obr´azku 5.21 je po-tom vidˇet porovn´an´ı vyuˇzit´ı m´ısta v paketu pˇr´ı pouˇzit´ı p˚uvodn´ıho a nov´eho protokolu. V tomto pˇr´ıkladu pˇr´ıkazy p˚uvodn´ıho protokolu zab´ıraj´ı 75 B a nov´eho protokolu pouze 48 B.

5.3 Casov´ ˇ e znaˇ cky

V pˇredchoz´ıch dvou ˇc´astech byly uvedeny metody pro sd´ılen´ı dat. Klient m˚uˇze napˇr´ıklad pomoc´ı vrstvy sd´ılet na serveru nejen polohu objektu s = (x, y, z), ale m˚uˇze to b´yt i tˇreba jeho rychlost ~v = (vx, vy, vz) a zrychlen´ı

~a = (ax, ay, az). D˚uvodem pro sd´ılen´ı rychlosti a zrychlen´ı m˚uˇze b´yt snaha dos´ahnout spojit´eho pohybu objekt˚u i pˇri ztr´atˇe nˇekter´ych paket˚u. Klient pˇrij´ımaj´ıc´ı tyto informace ovˇsem potˇrebuje ke spr´avn´emu dopoˇc´ıt´an´ı aktu´aln´ı polohy objektu pomoc´ı vztahu 5.3 i informaci o ˇcasu t0, kdy byla poloha, rychlost a zrychlen´ı u dan´eho objektu stanoveny.

x(t1) = x(t0) + vx(t0)(t1 − t0) + 12ax(t0)(t1− t0)2 y(t1) = y(t0) + vy(t0)(t1 − t0) + 12ay(t0)(t1− t0)2 z(t1) = z(t0) + vz(t0)(t1− t0) + 12az(t0)(t1− t0)2

(5.1)

Klient pos´ılaj´ıc´ı informaci o rychlosti a zrychlen´ı mus´ı tedy pos´ılat i infor-maci o ˇcasu t0. Jelikoˇz se simulace pohybu v´ıce objekt˚u vˇetˇsinou vypoˇc´ıt´av´a pro jeden ˇcasov´y okamˇzik, tak je efektivn´ı hodnotu t0 sd´ılet pro v´ıce pˇr´ıkaz˚u pomoc´ı jednoho pˇr´ıkazu Time Stamp jeˇz je uveden na obr´azku. Tento ˇcas je potom platn´y pro vˇsechny n´asleduj´ıc´ı pˇr´ıkazy v dan´em paketu.

0 1 1 2 2 3

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +---+---+---+---+

| OpCode=117 | Length=14 | |

+---+---+ +

| Time (Seconds) |

+ +---+---+

| | Time (Microseconds) (high) |

+---+---+---+---+

| Time (microseconds) (low) | +---+---+

Obr´azek 5.22: Struktura pˇr´ıkazu pro nastaven´ı ˇcasov´e znaˇcky

Chceme-li vyj´adˇrit, ˇze v dan´em paketu jsou n´asleduj´ıc´ı pakety bez ˇcasov´e

znaˇcky, tak je potˇreba vloˇzit do paketu pˇr´ıkaz Time Stamp, kdy poloˇzka Time (seconds) m´a hodnotu 264 a poloˇzka Time (Microseconds) m´a hodnotu 232.

Cas je vyj´ˇ adˇren pomoc´ı dvou hodnot podobnˇe jako UNIXov´y ˇcas. Hod-nota (64-bitov´y integer) v sekund´ach vyjadˇruje UTC ˇcas od p˚ulnoci 1. ledna 1970. Druh´a hodnota vyjadˇruje ˇcas v mikrosekund´ach od posledn´ı ukonˇcen´e sekundy.

Dalˇs´ı podm´ınkou pro korektn´ı fungov´an´ıˇcasov´ych znaˇcek je synchronizace ˇ

casu na jednotliv´ych klientech. Protokol Verse ˇz´adn´y takov´y mechanismus neposkytuje, takˇze klienti pouˇz´ıvaj´ıc´ı pˇr´ıkaz Time Stamp si mus´ı synchro-nizovat ˇcas napˇr´ıklad pomoc´ı protokolu NTP [27]. NTP protokol umoˇzˇnuje v z´avislosti na kvalitˇe spojen´ı nastavit ˇcas s pˇresnost´ı aˇz 0,2 ms.

Pokud nastane situace, ˇze by klient nemˇel ˇcas synchronizovan´y korektnˇe a hodiny by se mi zpoˇzd’ovaly, tak se m˚uˇze st´at, ˇze ˇcas t0pˇrijat´y pomoc´ı pˇr´ıkazu Time Stamp bude napˇred pˇred jeho aktu´aln´ım ˇcasem t1. V´ypoˇcet polohy pomoc´ı vztahu 5.3 by potom vedl k nekorektn´ım v´ysledk˚um. V pˇr´ıpadˇe, ˇze je t0 > t1 nen´ı moˇzn´e prov´adˇet estimaci aktu´aln´ı polohy objektu, ale je nutn´e pouˇz´ıt pouze pˇrijatou informaci o poloze a rychlost i zrychlen´ı ignorovat.

Kapitola 6

Implementace

Tato kapitola neobsahuje pouze popis implementace, ale mˇela by d´at n´avrh a doporuˇcen´ı, jak efektivnˇe prov´adˇet implementaci Verse serveru i kli-enta. Jedn´a se pˇredevˇs´ım o implementaci resend mechanismu, kde je vyˇ zado-v´ano, aby byla pos´ıl´ana pouze aktu´aln´ı data.

V´ysledn´a implementace protokolu Verse je naprogramov´ana v jazyku C a vyuˇz´ıv´a z knihovny OpenSSL implementaci protokolu TLS a DTLS. D´ale je vyuˇz´ıv´ana knihovna pthread pro pr´aci s vl´akny. Pouˇzit´e technologie umoˇzˇnuj´ı snadn´e portov´an´ı na r˚uzn´e platformy.

6.1 Server

Pˇri implementaci Verse serveru byl kladen d˚uraz na dosaˇzen´ı maxim´aln´ıho v´ykonu a propustnosti. Proto byl implementov´an jako v´ıcevl´aknov´a apli-kace. Server poslouch´a na poˇzadavky klient˚u v samostatn´em vl´aknˇe pomoc´ı TCP soketu, kter´y je vytvoˇren pomoc´ı syst´emov´eho vol´an´ı listen(). Kli-ent˚uv poˇzadavek na nov´e spojen´ı je detekov´an pomoc´ı syst´emov´eho vol´an´ı select(). Server n´aslednˇe vytvoˇr´ı pro nov´e spojen´ı samostatn´e vl´akno. Teprve v nov´em vl´aknˇe se provede TCP a TLS handshake. Po autentizaci uˇzivatele a dohodnut´ı nov´eho UDP spojen´ı je pro UDP spojen´ı vytvoˇreno dalˇs´ı tzv.

datagramov´e vl´akno. Zde m˚uˇze probˇehnout DTLS handshake a n´aslednˇe handshake datagramov´eho spojen´ı. Vlastn´ı komunikace s klientem prob´ıh´a v tomto vl´aknˇe.

Kdyˇz se nˇekter´y z handshak˚u nepovede nebo je dan´e spojen´ı zruˇseno, tak jsou obˇe vl´akna ukonˇcena a pˇr´ısluˇsn´e syst´emov´e prostˇredky jsou uvolnˇeny pro dalˇs´ı spojen´ı. Kromˇe v´yˇse zm´ınˇen´ych vl´aken je pˇri startu syst´emu vytvoˇreno jedno datov´e vl´akno, kter´e spravuje sd´ılen´a data. Komunikace mezi datov´ym vl´aknem a datagramov´ym vl´aknem se prov´ad´ı pomoc´ı speci´aln´ıch front, kter´e

Obr´azek 6.1: Vl´akna Verse serveru

budou pops´any v ˇc´asti 6.3 na stranˇe 97. Datov´e vl´akno pˇri pˇrijet´ı zpr´avy z fronty zpr´av nejprve zkontroluje korektnost pˇrijat´e zpr´avy (platnost ID, pˇr´ıstupov´a pr´ava, atd.). Kdyˇz pˇrijat´a zpr´ava neobsahuje ˇz´adnou chybu, tak pomoc´ı n´ı nastav´ı vlastn´ı kopii sd´ılen´ych dat a n´aslednˇe tuto zpr´avu zaˇrad´ı do fronty zpr´av klient˚u, kteˇr´ı byli pˇrihl´aˇseni k uzl˚um, skupin´am tag˚u nebo vrstv´am. Datov´e vl´akno by z´aroveˇn mˇelo zajistit, aby klient neobdrˇzel pˇr´ıkaz ruˇs´ıc´ı nˇejakou entitu (uzel, skupinu tag˚u, atd.), aniˇz by pˇred t´ım obdrˇzel odpov´ıdaj´ıc´ı pˇr´ıkaz pro vytvoˇren´ı dan´e entity. Kaˇzd´a v´yˇse zm´ınˇen´a entita by si mˇela uchov´avat pro kaˇzd´eho pˇrihl´aˇsen´eho klienta z´aznam o tom, v jak´em stavu se z jeho pohledu nach´az´ı. Pˇr´ısluˇsn´y stavov´y diagram je uveden na obr´azku 6.2.

Obecnˇe plat´ı doporuˇcen´ı, aby kaˇzd´e spojen´ı mˇelo minim´alnˇe jedno vl´akno a jeden samostatn´y TCP soket a UDP soket. Implementace vlastn´ıho vl´akna pro kaˇzd´e spojen´ı umoˇzˇnuje garantovat jednotliv´ym spojen´ım f´erov´e zach´azen´ı.

Poˇzadavek na vlastn´ı UDP soket pro kaˇzd´e spojen´ı vych´az´ı ze skuteˇcnosti, ˇze vˇetˇsina operaˇcn´ıch syst´em˚u alokuje pro vstupn´ı buffer UDP soketu pˇribliˇznˇe 100 KB. Z tohoto d˚uvodu je nezbytn´e, aby se vl´akno snaˇzilo co nejrych-leji tento buffer vyprazdˇnovat pomoc´ı syst´emov´eho vol´an´ı recf(). Velikost vstupn´ıho bufferu pro vˇsechny UDP sokety lze sice zvˇetˇsit netrivi´aln´ım z´ asa-hem administr´atora operaˇcn´ıho syst´emu, ale m´a to samozˇrejmˇe sv´a bezpeˇ

c-SUBSCRIBED

CREATING

CREATED DELETING

DELETED node_create

ack(node_create)

timeout

node_destroy

timeout UNSUBSCRIBED

ack(node_destroy) unsubscribe/timeout

Obr´azek 6.2: Stavy uzlu nostn´ı rizika.

P˚uvodn´ı Verse server byl implementov´an jako jednovl´aknov´a aplikace, kter´a pro vˇsechna spojen´ı pouˇz´ıvala jeden soket. Server potom pˇri velk´em poˇctu klient˚u a velk´em datov´em pˇrenosu nest´ıhal vyb´ırat dostateˇcnˇe rychle vstupn´ı buffer UDP soketu a operaˇcn´ı syst´em znaˇcnou ˇc´ast pˇrenesen´ych pa-ket˚u zahazoval.

6.2 Klient

Pro tvorbu Verse klient˚u byla vytvoˇrena knihovna a navrˇzeno nov´e API, jehoˇz podstatn´a ˇc´ast jiˇz je plnˇe implementov´ana. Komunikace klienta s kaˇ z-d´ym serverem prob´ıh´a tak´e pomoc´ı dvou samostatn´ych vl´aken, kter´a jsou vy-tvoˇrena po zavol´an´ı funkce verse send connect request(). Datagramov´e vl´akno je vytvoˇreno opˇet aˇz po ´uspˇeˇsn´e autentizaci a dohodnut´ı nov´eho datagra-mov´eho spojen´ı. Samotn´a v´ymˇena dat mezi hlavn´ım vl´aknem a datagra-mov´ym vl´aknem prob´ıh´a pomoc´ı funkc´ı zaˇc´ınaj´ıc´ıch ˇretˇezcem verse send , jeˇz jsou uvedeny v pˇr´ıloze na stranˇe 165.

Aby bylo hlavn´ı vl´akno schopn´e dost´avat data od datagramov´eho vl´akna, tak si mus´ı klient zaregistrovat pˇr´ısluˇsn´e callback funkce, jeˇz jsou opˇet uve-deny v pˇr´ıloze na stranˇe 165. Vlastn´ı v´ymˇena dat mezi vl´akny se prov´ad´ı opˇet pomoc´ı speci´aln´ı fronty pˇr´ıkaz˚u. V´yhoda v´ıce vl´aken u klienta spoˇc´ıv´a

Obr´azek 6.3: Vl´akna verse klienta

v tom, ˇze hlavn´ı vl´akno m˚uˇze b´yt zanepr´azdnˇeno napˇr´ıklad renderov´an´ım rastrov´eho obr´azku, v´ypoˇctem fyzik´aln´ı simulace, atd. Datagramov´e vl´akno mezit´ım prov´ad´ı komunikaci se serverem a uchov´av´a pˇrijat´a data dokud si o nˇe hlavn´ı vl´akno neˇrekne zavol´an´ım funkce verse callback update(). Verse klient samozˇrejmˇe m˚uˇze komunikovat s v´ıce servery z´aroveˇn a pro kaˇzd´e spo-jen´ı jsou vytvoˇrena dvˇe vl´akna, jak je uvedeno na obr´azku 6.3.

P˚uvodn´ı implementace protokolu Verse tak´e poskytovala knihovnu umoˇzˇ nu-j´ıc´ı implementaci Verse klient˚u. Komunikace ovˇsem neprob´ıhala v samo-statn´em vl´aknˇe, ale jen v okamˇzic´ıch, kdy Verse klient zavolal bud’ nˇejakou funkci zaˇc´ınaj´ıc´ı ˇretˇezcem verse send nebo funkci verse callback update().

Kdyˇz bylo hlavn´ı vl´akno klienta zanepr´azdnˇeno napˇr´ıklad renderov´an´ım, kter´e trvalo d´ele jak 30 sekund, server komunikaci s klientem ukonˇcil. Pro-gram´ator se mohl pokusit ˇreˇsit tento nedostatek implementac´ı komunikace ve vlastn´ım vl´aknˇe, ale knihovna implementuj´ıc´ı p˚uvodn´ı protokol Verse nebyla naprogramov´ana jako vl´aknovˇe bezpeˇcn´a. Napˇr´ıklad v´ysledek vol´an´ı funkce verse session get() z´aviselo na hodnotˇe glob´aln´ı promˇenn´e.

6.3 Fronta pˇ r´ıkaz˚ u

Jednotliv´a vl´akna na serveru i klientovi si mezi sebou potˇrebuj´ı efektivnˇe pˇred´avat data. Kdyby byla pouˇzita jednoduch´a fronta pˇr´ıkaz˚u, mohlo by doj´ıt

k situaci, kdy hlavn´ı vl´akno zaplˇnuje frontu pˇr´ıkaz˚u rychleji neˇz je datagra-mov´e vl´akno schopn´e odes´ılat. N´asledkem toho by se mohly v jednom paketu ocitnout dva pˇr´ıkazy se stejnou adresou, coˇz je znaˇcnˇe neefektivn´ı, protoˇze

k situaci, kdy hlavn´ı vl´akno zaplˇnuje frontu pˇr´ıkaz˚u rychleji neˇz je datagra-mov´e vl´akno schopn´e odes´ılat. N´asledkem toho by se mohly v jednom paketu ocitnout dva pˇr´ıkazy se stejnou adresou, coˇz je znaˇcnˇe neefektivn´ı, protoˇze