Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. iOS SDK
Code

Vytvorenie hra s Bonjour - odosielanie dát

by
Difficulty:IntermediateLength:LongLanguages:

Slovak (Slovenčina) translation by Tereza Foretová (you can also view the original English article)

V predchádzajúcom článku, sme položili základy sieťovú súčasť hry tým, že umožňuje používateľovi hostiteľa alebo pripojiť hru. Na konci tutorial sme úspešne nadviazala spojenie medzi dvoma zariadeniami bežiace aplikácie samostatne. V tomto tutoriále, sme sa bližšie pozrieť ako sme posielanie údajov z jednej zásuvky do druhého.


Úvod

Ako sme videli v predchádzajúcich tutoriál, CocoaAsyncSocket knižnica umožňuje prácu s sockets pomerne ľahko. Avšak, tam je viac k príbehu ako odosielanie jednoduchý reťazec z jedného zariadenia do druhého, tak ako v predchádzajúcom tutoriálu. V prvom článku tejto série, som napísal, že protokol TCP môžete spravovať nepretržitý prúd údajov v dvoch smeroch. Problém však je, že doslova je nepretržitý prúd údajov. TCP protokol sa postará o odosielanie dát z jedného konca pripojenie na druhý, ale je to na prijímači zmysel čo sa odosiela prostredníctvom tohto pripojenia.

Existuje niekoľko riešení tohto problému. Protokol HTTP je postavený na protokolu TCP, odosiela HTTP hlavičku s každej požiadavke a odpovedi. HTTP hlavička obsahuje informácie o žiadosti alebo odpovede, ktoré prijímača môžete použiť zmysel prichádzajúce prúd údajov. Jednou z kľúčových súčastí HTTP hlavičky je dĺžka tela. Ak príjemca vie Dĺžka tela žiadosť alebo odpoveď, môžete extrahovať telo z prichádzajúcich prúdu údajov.

To je skvelé, ale ako prijímač vie, ako dlho je hlavička? Každé pole hlavičky HTTP končí s CRLF (Carriage Return, Line Feed) a HTTP hlavičky, sám tiež končí s CRLF. To znamená, že v hlavičke každej HTTP žiadosť a odpoveď končí s dvoma CRLFs. Keď príjemca číta prichádzajúce dáta čítať prúd, má iba vyhľadať tento vzor (dve po sebe idúce CRLFs) v načítaní prúdu. Pritom prijímača môžete identifikovať a extrahovať hlavičky HTTP žiadosť alebo odpoveď. Hlavičky extrahované, extrahovanie telo HTTP žiadosť alebo odpoveď je veľmi jednoduché.

Stratégie, ktoré budeme používať sa odlišuje od fungovania HTTP protokoly. Každý paket údajov, ktorú vám pošleme cez pripojenie predponou hlavičku, ktorá má pevnú dĺžku. V hlavičke nie je tak zložité, ako HTTP hlavičku. Hlavičky, ktoré budeme používať obsahuje jeden kus informácií, Dĺžka tela alebo paket, ktorý prichádza po hlavičke. Inými slovami, v hlavičke je nič viac ako počet, ktorý informuje prijímač dĺžky tela. S touto znalostí prijímača môžete úspešne extrahovať tela alebo paketov z prichádzajúcich prúdu údajov. Aj keď je jednoduchý prístup, funguje to prekvapivo dobre, ako uvidíte v tomto tutoriále.


1. pakety

Je dôležité pochopiť, že vyššie uvedených stratégií sú prispôsobené TCP protokol a pracujú len kvôli fungovania protokolu TCP. Protokol TCP robí jeho najlepšie zabezpečiť, že každý paket nedosiahne svoje miesto určenia v poradí, ktorá bola odoslaná; teda stratégií, ktoré som načrtol veľmi dobre fungovať.

Krok 1: Vytvorenie paket triedy

Hoci môžeme poslať akýkoľvek typ dát prostredníctvom protokolu TCP, odporúča sa poskytovať vlastné štruktúra držať dáta, by sme chceli poslať. Môžeme to dosiahnuť vytvorením vlastné paketov triedy. Výhoda tohto prístupu sa prejaví, akonáhle začneme používať paket triedy. Myšlienka je jednoduchá, hoci. Trieda je Objective-C triedy, ktorá drží dáta; tela, ak budete. Zahŕňa aj dodatočné informácie o pakete, nazývaný hlavičky. Hlavný rozdiel s protokolom HTTP je, že hlavičky a tela nie sú striktne oddelené. Paket triedy bude musieť zodpovedať NSCoding protokolu, čo znamená, že inštancie triedy môžu byť zakódované a dekódované. To je kľúčové, ak chceme poslať inštancie triedy paketov cez TCP spojenia.

Vytvorenie novej triedy Objective-C, aby bolo podtriedy NSObject, a to meno MTPacket (obrázok 1). Pre hru, že budujeme, paket triedy môže byť pomerne jednoduché. Trieda má tri vlastnosti, typ, akcie a údajov. Vlastnosť Typ umožňuje identifikovať účel paket, zatiaľ čo vlastnosť akcia obsahuje zámer paket. Údaje objekt sa používa pre ukladanie skutočný obsah alebo zaťaženie paketu. Všetko jasnejšie akonáhle začneme používať paket triedy v našej hre.

Creating a Game with Bonjour - Sending Data - Creating the Packet Class
Vytvorenie paket triedy

Chvíľku kontrolovať rozhranie MTPacket triede uvedené nižšie. Ako som už spomenul, je dôležité, že inštancie triedy môžu byť zakódované a dekódovať zhodné s protokolom NSCoding. Zodpovedať NSCoding protokolu, potrebujeme len zaviesť dva (požadované) metódy, encodeWithCoder: a initWithCoder:.

Ďalší dôležitý detail je, že typ a vlastnosti akcie sú typu MTPacketType a MTPacketAction, resp.. Môžete si nájsť typ definície v hornej časti MTPacket.h. Ak nie ste oboznámení s typedef enum, si môžete prečítať viac o tom na pretečenie zásobníka. To bude oveľa jednoduchšie pracovať s triedou MTPacket.

Triedy data objekt je Identifikácia typu. To znamená, že to môže byť ľubovoľný objekt Objective-C. Jedinou podmienkou je, že je v súlade s protokolom NSCoding. Väčšina členov nadácie rámca, napríklad NSArray, NSDictionary a NSNumber, zodpovedajú NSCoding protokol.

Aby sa ľahko inicializovať inštancie triedy MTPacket, prehlasujeme určený inicializačný výraz, ktorý trvá paketu údajov, typu a akcie ako argumenty.

Implementáciu triedy MTPacket by nemalo byť príliš ťažké, ak ste oboznámení s protokolom NSCoding. Ako sme videli vyššie, NSCoding protokol definuje dve metódy a oba sa vyžadujú. Oni sú automaticky vyvolajú, keď inštanciu triedy je kódovaný (encodeWithCoder:) alebo dekódované (initWithCoder:). Inými slovami, ste nikdy vyvolať tieto metódy sami. Uvidíme, ako to funguje o niečo neskôr v tomto článku.

Ako vidíte nižšie, vykonávania určený inicializačný výraz initWithData:type:action: nemôže byť jednoduchšie. V súbore implementácie je tiež zrejmé prečo sme deklarovali tri reťazcové konštanty v rozhraní triedy. Je dobrým zvykom používať konštanty pre kľúče, ktoré používate v NSCoding protokole. Hlavným dôvodom je výkon, ale preklepy. Kľúče, ktoré ste prejsť pri kódovaní vlastnosti triedy musia byť identické s kľúče, ktoré sa používajú pri dekódovanie inštancie triedy.

Krok 2: Odosielanie dát

Predtým, ako sme sa presunúť na ďalší kúsok skladačky, chcem sa uistiť, že trieda MTPacket funguje podľa očakávania. Aký lepší spôsob, ako vyskúšať ako odoslaním paketu, akonáhle je vytvorené spojenie? Akonáhle to funguje, môžeme začať refactoring logika siete prostredníctvom vyhradeného správcu.

Keď pripojenie je usadený, aplikácie inštancie hosting hry oznámené to vzývanie socket: didAcceptNewSocket: delegovať metóda GCDAsyncSocketDelegate protokolu. Zaviedli sme túto metódu v predchádzajúcom článku. Pozrite sa na jeho realizáciu nižšie osviežiť pamäť. Posledný riadok jeho realizácie teraz mali byť jasné. Povieme nový soket začať čítať údaje a míňame značku, integer, ako posledný parameter. Sme nechcete nastaviť časový limit (-1), pretože nevieme, kedy môžeme očakávať prvý paket dorazí.

Čo naozaj zaujíma nás však je prvý argument readDataToLength:withTimeout:tag:. Prečo sme sa prejsť sizeof(uint64_t) ako prvý argument?

Funkciu sizeof vracia dĺžku v bajtoch argumentom funkcie, uint64_t, ktorý je definovaný v stdint.h (pozri nižšie). Ako som už vysvetlil skôr v hlavičke, ktorá predchádza každý paket, ktorý pošleme má pevnú dĺžku (obr. 2), ktorý je veľmi odlišný od hlavičky HTTP žiadosť alebo odpoveď. V našom príklade Hlavička má len jeden cieľ, hovoriť prijímač veľkosť paketu, ktorá ju predchádza. Inými slovami, tým, že povie socket prečítať prichádzajúce údaje veľkosť hlavičky (sizeof(uint64_t)), vieme, že sme si prečítali kompletnú hlavičku. Analýza hlavičky, akonáhle je extrahovaná z prichádzajúcich prúdu údajov, prijímač vie veľkosti tela vyplýva, že v hlavičke.

Creating a Game with Bonjour - Sending Data - Using a Header with a Fixed Length
Pomocou hlavičky s pevnou dĺžkou

Importovať súbor hlavičky MTPacket triedy a doplniť vykonávanie socket: didAcceptNewSocket: ako je uvedené nižšie (MTHostGameViewController.m). Po nariaďuje nový soket spustiť monitorovanie prichádzajúcich prúdu údajov, sme vytvoriť inštanciu triedy MTPacket, naplnenie figuríny dát a prechádza paket sendPacket: metóda.

Ako som písal vyššie, môžeme len poslať binárnych údajov cez TCP spojenia. To znamená, že musíme kódovať MTPacket stupňa, sme vytvorili. Pretože MTPacket trieda zodpovedá NSCoding protokol, to nie je problém. Pozrite sa na sendPacket: metóda uvedené nižšie. Vytvoriť inštanciu NSMutableData a používať ho inicializovať kľúčované archivátor. NSKeyedArchiver trieda je podtriedou NSCoder a má schopnosť kódovať objekty zhodné s protokolom NSCoding. S kódovaním archivátor máme k dispozícii, budeme kódovať paket.

Potom vytvoríme ďalší NSMutableData stupňa, ktorý bude údajový objekt odovzdáme do zásuvky trochu neskôr. Údajový objekt, však len nedrží kódovaný MTPacket stupňa. Treba tiež zahrnúť hlavičku, ktorá predchádza kódované paket. Uložíme dĺžka kódované paket premennej s názvom headerLength, ktorá je typu uint64_t. Potom pridať hlavičky NSMutableData buffer. Ste na mieste & symbol predchádza headerLength? AppendBytes:length: metóda očakáva medzipamäte bajtov, nie hodnotu headerLength hodnotu. Nakoniec sme append obsah packetData do medzipamäte. Medzipamäť je potom odovzdaný na writeData:withTimeout:tag:. Knižnica CocoaAsyncSocket sa postará o natvrdlý kostrbata detaily Posielanie dát.

Krok 3: Príjem dát

Prijímať paketu sme práve poslali, musíme zmeniť triedu MTJoinGameViewController. Pamätajte si, že v predchádzajúcom článku, sme implementovali socket: didConnectToHost:port: delegovať metóda. Táto metóda sa uplatňuje pri nadviazaní spojenia potom klient sa pripojil hru. Pozrite sa na jej pôvodná implementácia nižšie. Rovnako ako sme to urobili v MTHostGameViewController triede, povieme socket začať čítať dáta bez časového limitu.

Úplné hlavičky predchádzajúcich paketových dát má prečítaní zásuvky vyvolá socket: didReadData:withTag: delegovať metóda. Tag, ktorý je odovzdaný je rovnakú značku v readDataToLength:withTimeout:tag: metóda. Ako vidíte nižšie, vykonávania socket: didReadData:withTag: je prekvapivo jednoduché. Ak tag sa rovná 0, míňame údaje premennej na parseHeader:, ktorý vráti hlavičky, čiže dĺžku paketu, vyplýva, že v hlavičke. Teraz vieme, že veľkosť kódované paket a Míňame tieto informácie na readDataToLength:withTimeout:tag:. Časový limit nastavený na 30 (v sekundách) a posledným parametrom tag je nastavená na 1.

Než sa pozrieme na implementáciu parseHeader:, poďme najprv pokračovať náš prieskum socket: didReadData:withTag:. Ak tag je rovná 1, vieme, že máme čítať kompletnú kódované paket. Analyzovať paket a opakujte cyklus hovorí pôsobeniu pozor na hlavičke ďalší paket, ktorý príde. Je dôležité, že míňame -1 timeout (časový limit), pretože nevieme, kedy ďalšej paket dorazí.

V parseHeader: metódy, funkciu memcpy robí všetky ťažké zdvíhanie pre nás. Môžeme kopírovať obsah dát v premennej headerLength typu uint64_t. Ak nie ste oboznámení s memcpy funkcia, môžete si prečítať viac o tom tu.

V parseBody:, robíme naopak čo sme robili v sendPacket: metóda MTHostGameViewController triedy. Môžeme vytvoriť inštanciu NSKeyedUnarchiver, prejsť čítame z čítať prúd údajov a vytvoriť inštanciu MTPacket dekódovanie dát pomocou kľúčované unarchiver. Dokázať, že všetko funguje ako má, môžeme prihlásiť paketu údajov, typu a akcie Xcode konzoly. Nezabudnite importovať hlavička súboru MTPacket triedy.

Spustiť dve inštancie aplikácie. Hosť hru na jednu inštanciu a pripojiť túto hru na strane druhej inštancie. Mali by ste vidieť obsah paketu je prihlásený ku konzole Xcode.


2. refactoring

Nie je vhodné dať sietí logika tried MTHostGameViewController a MTJoinGameViewController. To bude len nám problémy na ceste. Je vhodnejšie používať MTHostGameViewController a MTJoinGameViewController pre nadviazanie spojenia a absolvovanie pripojenie - socket - radič, ktorý je zodpovedný za riadenie a toku hry.

Zložitejšie je problém, problém má viac riešení a tieto riešenia sú často veľmi špecifický problém. Inými slovami, riešenie uvedené v tomto článku je životaschopnou možnosťou, ale nepovažujem to ako jediné riešenie. Pre jeden z mojich projektov, Pixelstream, som tiež používal Bonjour a knižnicu CocoaAsyncSocket. Môj prístup pre tento projekt je však veľmi odlišný, ako ten uvádzam tu. V Pixelstream, musím byť schopný odosielať pakety z rôznych miest v žiadosti a preto sa rozhodli použiť jeden objekt, ktorý spravuje pripojenie. V kombinácii s dokončením blokov a frontu paketov, toto riešenie funguje veľmi dobre pre Pixelstream. V tomto článku, nastavenie je však menej komplikované pretože problém je pomerne jednoduchý. Nechcem overcomplicate veci, ak nemusíte.

Stratégie, ktoré použijeme je jednoduchý. MTHostGameViewController a MTJoinGameViewController triedy majú delegát, ktoré je oznámené pri nadviazaní nového spojenia. Delegát bude naša MTViewController stupňa. Tá vytvorí herný ovládač, inštanciu triedy MTGameController, ktorá spravuje pripojenia a toku hry. MTGameController trieda bude mať na starosti pripojenie: odosielanie a príjem paketov, ako aj užívať vhodné akciu na základe obsahu paketov. Keby ste pracovať na zložitejšie hry, potom by bolo dobré oddeliť siete a herné logiku, ale nechcete, aby overcomplicate veci moc v tomto príklade projektu. V tejto sérii, chcem sa uistiť, že rozumiete, ako rôzne kúsky dohromady tak, že môžete prispôsobiť túto stratégiu do akéhokoľvek projektu pracujete.

Krok 1: Vytvorenie delegátom protokolov

Delegát protokoly, ktoré musíme vytvoriť nie sú zložité. Každý protokol má dve metódy. Hoci som alergický na duplicitu, myslím, že je užitočné vytvoriť samostatné delegát protokol pre každú triedu, MTHostGameViewController a MTJoinGameViewController triedy.

Vyhlásenie delegát pre triedu MTHostGameViewController je uvedený nižšie. Ak ste vytvorili vlastné protokoly pred, nenájdete žiadne prekvapenia.

Delegát protokol deklarované v MTJoinGameViewController triede je takmer identický. Jediné rozdiely sú metóda podpisy delegát metódy.

Musíme tiež aktualizovať hostGame: a joinGame: akcie v MTViewController triede. Jediná zmena robíme je priradenie MTViewController stupňa ako delegát inštancií MTHostGameViewController a MTJoinGameViewController.

To tiež znamená, že MTViewController triedy musí zodpovedať MTHostGameViewControllerDelegate a MTJoinGameViewControllerDelegate delegovať protokoly a implementovať metódy na každý protokol. Sme sa pozrieť na implementáciu týchto delegovať metódy za pár chvíľ. Po prvé, chcel by som pokračovať, refactoring tried MTHostGameViewController a MTJoinGameViewController.

Krok 2: Refactoring MTHostGameViewController

Prvá vec, ktorú musíme urobiť, je aktualizovať socket: didAcceptNewSocket: delegovať metóda GCDAsyncSocket delegát protokolu. Metóda sa stáva oveľa jednoduchšie, pretože práca dojata delegátovi. Sme tiež vyvolať endBroadcast, Pomocník metóda, ktoré budeme realizovať v okamihu. Keď pripojenie je usadený, môžeme odmietnuť Zobraziť radič hostiteľa a hra môže začať.

V endBroadcast, dbáme, aby sme všetko upratať. To je tiež vhodný okamih na aktualizáciu zrušiť: akcie, ktoré sme nechali nedokončený v predchádzajúcom článku.

V zrušiť: akcia, budeme informovať delegát vyvolaním druhá metóda delegát a my tiež vyvolať endBroadcast, ako sme predtým.

Pred pokračovaním našej refactoring spree, je dobrým zvykom veci upratať Zobraziť controller dealloc metódy ako je uvedené nižšie.

Krok 3: Refactoring MTJoinGameViewController

Podobne ako to, čo sme robili v socket: didAcceptNewSocket: metódy, potrebujeme na aktualizáciu socket: didConnectToHost:port: metódy, ako je uvedené nižšie. Budeme informovať delegát, zastaviť prehliadania služieb a zamietol Zobraziť controller.

Aktualizujeme aj zrušiť: a dealloc metódy ako sme to urobili v triede MTHostGameViewController.

Uistite sa, že neporušili sme nič, implementovať metódy delegát oboch protokolov v MTViewController triede, ako je uvedené nižšie a spustiť dve inštancie aplikácie otestovať, či neporušili sme nič. Ak všetko pôjde dobre, mali by ste vidieť vhodné správy prihlásenia do konzoly Xcode a modálne Zobraziť ovládače automaticky odvolá, keď hra je pripojený, čiže pri nadviazaní spojenia.


3. Realizácia hracieho zariadenia

Krok 1: Vytvorenie herného ovládača triedy

MTViewController trieda bude poverená spracovaním pripojenie a hru toku. Vlastné zariadenie triedy, MTGameController bude mať na starosti to. Jedným z dôvodov pre vytvorenie triedy samostatný radič je, že akonáhle sa hra začala, nebudeme robiť rozdielu medzi serverom a klientom. Preto je vhodné mať radič, ktorý je zodpovedný za pripojenie a hru, ale že nerobí rozdiel medzi serverom a klientom. Ďalším dôvodom je, že jedinou zodpovednosťou tried MTHostGameViewController a MTJoinGameViewController je vyhľadávanie hráčov v lokálnej sieti a pripájania. Oni nemali žiadne iné povinnosti.

Vytvoriť Nová podtrieda NSObject a nazvite ho MTGameController (obr. 3). Rozhranie MTGameController triede je docela jednoduché, ako môžete vidieť nižšie. To sa zmení, akonáhle sme začať s vykonávaním herné logiku, ale bude to teraz. Určený inicializačný výraz trvá jeden argument, GCDAsyncSocket stupňa, ktorý bude riadiť.

Creating a Game with Bonjour - Sending Data - Creating the Game Controller Class
Vytvorenie herného ovládača triedy

Prv než sme používať initWithSocket:, musíme vytvoriť súkromný majetok pre zásuvky. Vytvorenie triedy rozšírenie, ako je uvedené nižšie a vyhlásiť objekt typu GCDAsyncSocket s názvom Konvertory. Tiež som vzal slobodu import hlavička súboru MTPacket triedy a definovať TAG_HEAD a TAG_BODY, aby bolo ľahšie pracovať s Tagy GCDAsyncSocketDelegate delegát metód. Samozrejme, MTGameController triedy musí zodpovedať protokolu GCDAsyncSocketDelegate delegát všetko fungovať.

Vykonávanie initWithSocket: je uvedený nižšie a nemali by byť príliš prekvapujúce. Sme ukladanie odkazov do zásuvky v súkromnom vlastníctve, ktoré sme práve vytvorili, set hracie ako socket delegovať a povedať socket začať čítať prichádzajúce údaje, t. j. zachytiť prvej hlavičke, že príde.

Zvyšok refactoring proces nie je zložitý buď pretože sme už urobili väčšinu práce v MTHostGameViewController a MTJoinGameViewController triedy. Začnime tým, že pohľad na implementáciu protokolu GCDAsyncSocketDelegate delegáta. Vykonávanie nelíši od čo sme videli skôr v MTHostGameViewController a MTJoinGameViewController triedy.

Vykonávanie sendPacket:, parseHeader:, a parseBody: nie sú žiadne odlišné buď.

ParseBody: metóda bude hrať dôležitú úlohu v príbehu o niečo neskôr, ale bude to teraz. Naším cieľom v tomto bode je zohnať všetko funguje opäť, po dokončení procesu refactoring.

Než sme sa ďalej, je potrebné implementovať metódu dealloc MTGameController triedy, ako je uvedené nižšie. Pri každom zrušení vyhradenia herný ovládač, stupňa treba prerušiť spojenie volaním odpojiť na inštanciu GCDAsyncSocket.

Krok 2: Vytvorenie ďalší zástupca protokolu

MTViewController trieda bude spravovať hracie zariadenie a komunikovať s ním. MTViewController zobrazí hru a umožňujú používateľovi prácu s ním. MTGameController a MTViewController prípadoch je potrebné komunikovať medzi sebou a budeme používať ďalší delegát protokol pre tento účel. Komunikácia je asymetrický, Zobraziť controller pozná herný ovládač, ale herný ovládač nevie o ovládači view. Budeme rozširovať protokolu, ako ideme, ale teraz Zobraziť controller by sa oznámia len vtedy keď sa stratí pripojenie.

Prehodnocovať MTGameController.h a vyhlásiť delegát protokol, ako je uvedené nižšie. Okrem toho verejný majetok je vytvorený pre hracie zariadenie delegáta.

Môžeme okamžite dať delegát protokolu používať oznámením hracie zariadenie delegát v jednom z GCDAsyncSocketDelegate delegát metódy, socketDidDisconnect:withError: aby som bol presný.

Krok 3: Aktualizácia MTViewController triedy

Posledným kúskom refactoring puzzle je uvedenie MTGameController na použitie. Vytvorenie súkromného vlastníctva v MTViewController triede, MTViewController trieda MTGameControllerDelegate protokolu v súlade s a importovať hlavička súboru MTGameController triedy.

V ovládači: didHostGameOnSocket: a prevádzkovateľ: didJoinGameOnSocket:, môžeme vyvolať startGameWithSocket: a prejsť Konvertory nové pripojenie.

V startGameWithSocket: Pomocník metóda, môžeme vytvoriť inštanciu inštanciu triedy MTGameController zadanφm socket a store odkaz herného ovládača view controller gameController vlastnosť. Zobraziť controller slúži aj ako hracie zariadenie delegátom, ako sme diskutovali skôr.

V controllerDidDisconnect: delegovať metóda MTGameControllerDelegate protokolu môžeme vyvolať metódu helper koncovka v ktorej môžeme vyčistiť hracie zariadenie.

Uistite sa, že všetko funguje, sme mali otestovať náš setup. Poďme otvoriť XIB súbor MTViewController a pridať iné tlačidlo v hornej ľavej s názvom odpojiť (obrázok 4). Používateľa môžete Poklepaním na toto tlačidlo, keď ona chce skončiť alebo opustiť hru. Ukážeme toto tlačidlo len v prípade, nadviazať spojenie. Keď pripojenie je aktívne, môžeme skryť tlačidlá hostiť a pripojiť sa k hre. Vykonať potrebné zmeny vo MTViewcontroller.xib (obr. 4), vytvoriť odbytiská pre každé tlačidlo MTViewController.h, a pripojenie výstupov do MTViewcontroller.xib.

A konečne, vytvoriť akciu s názvom odpojiť: v MTViewController.m a spojiť ju s názvom tlačidlo odpojiť.

Creating a Game with Bonjour - Sending Data - Updating the User Interface
Aktualizácia používateľského rozhrania

V setupGameWithSocket: metódy, sme sa schovať, hostButton a joinButton a ukážeme disconnectButton. V metóde koncovka robíme pravý opak uistite sa, že používateľ môže hostiť alebo pripojiť hru. Musíme tiež skryť disconnectButton v Zobraziť controller viewDidLoad metóda.

Otestovať, či všetko stále funguje, musíme poslať paket test ako my o niečo skôr v tomto článku. Vyhlásiť metódu s názvom testConnection v MTGameController.h a realizovať, ako je uvedené nižšie.

Zobraziť controller mali uplatniť túto metódu kedykoľvek vytvoriť nové spojenie. Dobré miesto na to je v ovládač: didHostGameOnSocket: delegovať metóda po herný ovládač nebol inicializovaný.

Spustiť aplikáciu opäť na overenie, že všetko je stále pracuje po procese refactoring.


4. upratovanie

Teraz je čas upratať triedy MTHostGameViewController a MTJoinGameViewController sa zbavíme akýkoľvek kód, ktorý už patrí do týchto tried. MTHostGameViewController triedy, to znamená odstránenie sendPacket: metóda a pre triedy MTJoinGameViewController, to znamená odstránenie socket: didReadData:withTag: metóda CocoaAsyncSocketDelegate delegát protokolu, ako aj kód > parseHeader: a parseBody: pomocné metódy.


Zhrnutie

Môžete si predstaviť, že tento článok opustil vás trochu omámený alebo ohromený. Tam bolo veľa aby sa a spracovať. Avšak, chcem zdôrazniť, že zložitosť tohto článku bola primárne zapríčinená štruktúry samotnej aplikácie a nie toľko ako prácu s Bonjour a knižnicu CocoaAsyncSocket. To je často skutočnou výzvou architekt aplikácie v takým spôsobom, minimalizovať závislostí a aby aplikácia chudé, výkonný a modulárne. To je hlavný dôvod, prečo sme presunuté naše počiatočné vykonávanie logické siete.

Teraz máme Zobraziť controller, ktorý sa postará o zobrazenie hra užívateľa (MTViewController) a radič (MTGameController), ktorý zvláda logické hry a pripojenie. Ako som už spomenul, je možné oddeliť pripojenie a hra logic vytvorením samostatnej triedy pre každú z nich, ale pre túto jednoduchú aplikáciu, ktorá nie je potrebné.


Záver

Sme urobili významný pokrok s náš herný projekt, ale tam je jedna zložka chýba... hra! V ďalšej splátky tejto série, môžeme vytvoriť hru a využiť nadácie, ktoré sme vytvorili tak ďaleko.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.