Rozdíly

Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.

Odkaz na výstup diff

Následující verze
Předchozí verze
public:objectdebugging_2011_communication [2011/09/12 20:30]
xbrukner vytvořeno - původní text při zjednodušení úlohy
public:objectdebugging_2011_communication [2018/02/24 19:10] (aktuální)
Řádek 1: Řádek 1:
 +====== Komunikace mezi serverem a klientem ======
  
 +=== Obecný postup výměny zpráv ===
 +Samotná hra bude probíhat takto (předpokladem je jeden server a dva klienti):
 +  * První klient požádá server o vytvoření hry (//​createGame//​)
 +  * Server hru vytvoří a pošle zpátky prvnímu klientovi ID této hry
 +  * První klient po obdržení ID hry pošle zprávu druhému klientovi, jestli se nechce přidat k té hře (//​gameInvitation//​)
 +  * Protože se druhý klient ke hře připojit chce, pošle prvnímu klientovi potvrzení
 +  * První klient následně oznámí serveru jméno druhého hráče do hry (//​joinGame//​)
 +  * Server to potvrdí a tím vyzve prvního hráče k prvnímu tahu
 +  * První klient následně umístí první tah na hrací plochu (//move//)
 +  * Server požadavek zpracuje, pošle zpátky potvrzení a druhému hráči pošle souřadnice soupeřova tahu a výzvu, že má hrát (//​yourMove//​)
 +
 +(V závorkách jsou jména jednotlivých zpráv z protokolu, viz dále.)
 +==== Popis tříd Client a Server ====
 +=== Server ===
 +Server je objekt, který komunikuje s ostatními pouze pomocí Network - přijímá zprávy a odpovídá na ně. Sám od sebe žádnou činnost nedělá (pouze reaguje). Proto jeho jediné veřejné metodou jsou konstruktor (který přijímá jeden std::string jako jméno) a doAction (přepsaný z NetworkObject). Jméno v konstruktoru bude stejné jako jeho jméno v síti. Vytvářet se tedy bude v podstatě takto:
 +<code c++>​Network::​instance().add(new Server("​server"​),​ "​server"​);</​code>​
 +Zprávy, které server přijímá, mohou být i **nevalidní** - tj ne nutně takové, jaké jsou definovány v protokolu. Pokud obdrží server neplatnou zprávu, tak buď v tichosti skončí (pokud nedostal identifikaci příjemce),​ nebo pošle zpět chybovou zprávu (formát viz protokol).
 +=== Klient ===
 +Klient komunikuje se servery, s ostatními hráči a s uživatelem (technicky se pořád posílají stejné zprávy pro NetworkObject). S uživatelem se komunikuje pouze na vyzvání (není žádný "​příkazový řádek"​) - až na založení hry, kdy se při zavolání konstruktoru uživatele zeptá, zda-li chce hru založit. Klient má stejně jako server jen konstruktor (který přijímá stejně jako Server jméno) a metodu doAction. Konkrétní pracovní postup je ve zkratce popsán výše (tam jsou jména metod), podrobněji je pak níže (v sekci Protokol). Jediná metoda nezmíněná nahoře je metoda //active//, kterou popisuji v protokolu - ta je určena ke kontrole, kolik objektů typu Client je ještě aktivních.
 +
 +Všechny zprávy, které klient přijme, budou vždy ve **validním formátu** - tj buď korektní odpověď, nebo chybová zpráva. Korektní odpověď musí zpracovat, chybovou zprávu vytisknout a stát se neaktivním (viz protokol, akce //​active//​).
 +
 +==== Výstup klienta ====
 +Výstup klienta bude vypadat takto:
 +  * Jako první na řádku bude ''​[jméno klienta]''​ následované mezerou
 +  * Dále bude jméno akce (jména zpráv ((startGame,​ createGame... viz protokol))) následované v závorkách parametry jménem serveru a ID hry (oddělené čárkou a mezerou, třeba ''​createGame(server,​ 0)''​),​ a na konci bude dvojtečka a mezera
 +    * V případě akce startGame, která tyto informace zjišťuje, nejsou v závorkách parametry - správný formát je ''​[jméno klienta] startGame: ''​
 +  * Dále bude následovat zpráva. Tato zpráva může mít jakýkoliv text, ale měla by sdělovat podstatné informace (jako třeba co se stalo, plus informace ze zprávy - což je případ pozvání ke hře (zobrazit parametry hry) a tah soupeře (kam vlastně položil kámen)).
 +Vstup od uživatele bude následující:​
 +  * **Můžete předpokládat,​ že je správného formátu (tj pokud chcete tři čísla jako parametry hry, dostanete tři čísla).**
 +  * Pokud se ptáte otázkou ano/ne (založení hry, přijmutí pozvánky), dostanete odpověď //yes// nebo //no//.
 +  * Pokud se ptáte na jméno či ID serveru/​klienta,​ tak můžete předpokládat,​ že jméno nezačíná číslicí. Na druhou stranu můžete dostat jak jméno, tak ID. Dále je zde potřeba ošetřit, jestli daný objekt existuje (ale není potřeba kontrolovat,​ jestli se jedná o správný objekt ((o instanci Server, když chcete server a analogicky u klienta))).
 +  * Vstup bude vždy končit enterem.
 +
 +Komunikace ve hře tedy může vypadat takto:
 +<​code>​
 +[client] startGame: Do you want to start a new game?
 +yes
 +[client] startGame: Enter server name or ID: 
 +server
 +[client] startGame: Enter game parameters (x, y, number of stones): ​
 +1 1 1
 +[client2] startGame: Do you want to start a new game?
 +no
 +[client] createGame(server,​ 0): Game created.
 +[client] gameInvitation(server,​ 0): Enter name or ID of other client to invite to this game: 
 +client2
 +[client2] gameInvitation(server,​ 0): Player client has invited you to game (1, 1, 1). Do you want to join this game?
 +yes
 +[client] gameInvitation(server,​ 0): Player client2 accepted your game invitation.
 +[client] joinGame(server,​ 0): Sending server the other player to join game.
 +[client] joinGame(server,​ 0): Server accepted the other player.
 +[client] move(server,​ 0): Place your move:
 +0 0
 +[client] move(server,​ 0): You have won!
 +[client2] yourMove(server,​ 0): Opponent player has placed his move to (0, 0) and won the game. You have lost.
 +</​code>​
 +
 +
 +
 +==== Komunikační protokol ====
 +Pomocné struktury (pokud se na ně odkážu dále, nahraďte je za zdejší seznam).
 +  * Identifikace serveru/​klienta - může být jak string, tak číslo (pokud je již posláno ve zprávě, tak je platné)
 +  * parametry hry 
 +    * rozměr osy x (číslo, > 0)
 +    * rozměr osy y (číslo, > 0)
 +    * počet kamenů v řadě nutných k vítězství (číslo, > 0)
 +  * identifikace hry
 +    * identifikace serveru (identifikace)
 +    * ID hry (číslo)
 +  * položení kamene
 +    * x-ová souřadnice (číslo, > 0)
 +    * y-ová souřadnice (číslo, > 0)
 +  * pozvání ke hře
 +    * od koho - jméno hráče (string)
 +    * identifikace hry
 +  * stav - číslo
 +    * 0 -> nepovedlo se
 +    * 1 -> povedlo se
 +V momentě kdy se posílá nějaká zpráva, tak jako první parametr je vždy jméno akce. Stejně tak se na většinu akcí odpovídá zpět ((výjimkou je akce //​yourMove//,​ kterou posílá server hráči, že je na tahu)), a pak je jméno akce stejné jako u příchozí zprávy.
 +
 +Následují akce, které klient vykonává (vypisují se na výstup):
 +  * **startGame**
 +    * Založení hry.
 +    * Klient se nejdříve zeptá otázkou ano/ne, jestli si uživatel přeje založit hru. Pokud odpoví kladně, tak se nejdříve zeptá na identifikaci serveru a následně na parametry hry. S těmito parametry následně přejde na akci //​createGame//​.
 +    * __Pokud dostane neplatnou identifikaci serveru, tak vytiskne chybovou hlášku.__
 +    * //Toto je jediná akce, která se neposílá jako zpráva.//
 +  * **createGame**
 +    * Dotaz na založení hry na serveru.
 +    * Parametry odchozí zprávy (klient -> server):
 +      * identifikace zakládajícího hráče (identifikace)
 +      * parametry hry
 +    * Odpověď serveru (server -> klient):
 +      * stavová zpráva
 +      * text chyby (string) / identifikace hry
 +    * **Netiskne** nic při zavolání na straně klienta. Při přijetí této zprávy od serveru vytiskne potvrzení o založení hry a přejde na akci //​gameInvitation//​.
 +  * **gameInvitation**
 +    * Pozvání druhého hráče ke hře.
 +    * Parametry pozvání (zakládající klient -> zvaný klient):
 +      * pozvání ke hře
 +      * parametry hry
 +    * Odpověď klienta (zvaný klient -> zakládající klient):
 +      * identifikace zvaného klienta (identifikace)
 +      * parametry hry
 +      * přijmutí pozvání (1 -> přijímám,​ 0 -> nepřijímám)
 +    * Zakládající klient se ptá uživatele na identifikace druhého hráče.
 +    * Zvaný klient vytiskne zprávu o tom, kdo ho zve k jaké hře a zeptá se ano/ne, jestli to hráč přijímá. Toto vytiskne pouze v momentě, kdy sám žádnou hru nehraje. Jinak vytiskne pouze zprávu o tom, že byl pozván, ale že už hraje, takže automaticky tu pozvánku odmítá. (A pozvánku odmítne.)
 +    * Zakládající klient následně při přijetí zprávy o pozvání vytiskne odpověď a
 +      * pokud klient pozvání přijal, přejde na akci //​joinGame//​
 +      * pokud pozvání nepřijal, tak přejde znovu na akci //​gameInvitation//​ (zase se zeptá na jméno klienta k pozvání)
 +  * **joinGame**
 +    * Zakládající hráč posílá tuto zprávu serveru, že má druhého hráče ke hře.
 +    * Dotaz serveru (klient -> server)
 +      * identifikace sebe sama (identifikace)
 +      * ID hry (číslo)
 +      * identifikace druhého hráče (identifikace)
 +    * Odpověď serveru (server -> klient)
 +      * stavová zpráva
 +      * text chyby (string) / identifikace hry
 +    * Klient tiskne zprávu o poslání dotazu serveru, stejně tak že to server přijal. Následně přejde na akci //move//.
 +  * **move**
 +    * Tah hráče
 +    * Dotaz serveru (klient -> server)
 +      * identifikace sebe sama (identifikace)
 +      * ID hry (číslo)
 +      * položení kamene
 +    * Odpověď serveru (server -> klient)
 +      * stavová zpráva
 +      * text chyby (string) / identifikace hry
 +      * stav hry - 0 -> hraje druhý hráč, 1 -> vyhrál jste
 +    * Klient se hráče zeptá na polohu kamene, kam chce zahrát. Při přijetí zprávy pouze vytiskne, jestli hráč vyhrál, nebo jestli se čeká na tah protivníka.
 +  * **yourMove**
 +    * Tato zpráva jde od serveru hráči, který právě nehrál, kam hrál protihráč a že je na tahu (pokud soupeř nevyhrál).
 +    * Zpráva (server -> klient)
 +      * identifikace hry
 +      * položení kamene
 +      * jste na tahu? - 1 -> hrajete, 0 -> prohrál jste
 +    * Po přijetí této zprávy vytiskne klient především souřadnice tahu soupeře a, pokud soupeř nevyhrál, přejde na //move//.
 +  * **active**
 +    * Tento typ zprávy je speciální a je použit pro sledování,​ jestli se ještě hraje.
 +    * Příchozí zpráva pro klienta
 +      * identifikace odesílatele (identifikace)
 +    * Odchozí zpráva od klienta
 +      * identifikace sebe sama (identifikace)
 +      * jsem aktivní? 0 -> nejsem, 1 -> jsem
 +    * Hráč je neaktivní pokud
 +      * nemá ani založenou hru (__ale je aktivní, pokud poslal serveru žádost o založení hry__), ani není k žádné hře pozván
 +      * pokud se vyskytla chyba (přijal chybu od serveru)
 +      * __čeká na yourMove__
 +Formát chybové zprávy je vždy
 +  * jméno akce (string)
 +  * 0 (stavová zpráva)
 +  * chybová hláška (string)
QR Code
QR Code public:objectdebugging_2011_communication (generated for current page)