• No results found

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.