
2015-07-18 | &δφ±πnbsp; 發布者:梁國(guó)芳 &→nbsp;| 查看(kàn):3320次
IT新聞以下(xià)為(wèi)譯文(wén)
縱觀過去(qù)10年(nián)的(de)遊戲領域,∏∞δ單機(jī)向網絡發展已成為(wèi)一(yī)個(g耥)非常大(dà)的(de)趨勢。然而,為(wèi¶₩ε)遊戲添加網絡支持的(de)過程中往往存在著(zhe)大(dàγ♥&∏)量挑戰,而據近(jìn)幾年(nián)的(de)工(gōng)作(zuò→₽)經驗(不(bù)僅參與了(le)這(zhè)一(yī)衍變,同樣也©'γ∞(yě)為(wèi)大(dà)量開(kāi)發者提供資'≠γ÷訊支持)來(lái)看(kàn),許多(duō)遊戲開(kāi)發者>××≥甚至都(dōu)違反了(le)“打造一(yī)個(×↓gè)優秀網絡應用(yòng)程序&rdqπφ€Ωuo;應該堅守的(de)一(yī)些(xiē)基本原≥®則。因此,應用(yòng)程序往往會(huì)面臨著(zhe)&ldqπ'uo;frozen” UIs、莫∏π名的(de)斷線(在其他(tā)程序互聯網訪問(wèn)正常時(shí)©★>™)、不(bù)定期崩潰,以及峰值期間(ji♠∞§₩ān)的(de)服務器(qì)過載等問(wèn)題。毫無疑問(wè♣©∏n),這(zhè)些(xiē)問(wèn)題将直接★ 影(yǐng)響到(dào)玩(wán)家(jiā)的(de♥♣→)遊戲體(tǐ)驗,同時(shí)其直接程度也(yě)遠(yuǎn¶♣©)超管理(lǐ)員(yuán)和(hé)圖形開(kāε$≥∑i)發者的(de)想象。慶幸的(de)是(sh↔γ∑★ì),這(zhè)些(xiē)問(wèn)題處理(lǐ)起來(lái)§± 并不(bù)複雜(zá),有(yǒu)些(xiē)甚至是(shì)一'Ω↕(yī)點就(jiù)明(míng)。
因此,這(zhè)裡(lǐ)将通(tōng)過一(™♣±yī)系列博文(wén)來(lái)布道(dào)網絡開←♥×(kāi)發的(de)某些(xiē)理(lǐ)念,其中大(dà)部分(f☆¶₽ēn)是(shì)遊戲引擎開(kāi)發者不(bù)曾留意的≤←¶(de)。當然對(duì)于某些(xiē)朋(péng)友(yǒ∑&πu)來(lái)說(shuō),有(yǒu)些£×≠(xiē)觀點可(kě)能(néng)你 •<(nǐ)已經接觸到(dào)了(le),但(dàn)毫無疑問(wèn)的(de € )是(shì),它對(duì)大(dà)量遊戲開♠¥™α(kāi)發者都(dōu)是(shì)有(yǒu)價值的(dλ e)。因此,對(duì)于期望打造出類似遊 ≥♣戲或證券交易這(zhè)類高(gāo)交互應用(yòng)程序的(®¶ >de)開(kāi)發者,這(zhè)些(xiē≈±)建議(yì)值得(de)一(yī)讀(dú)。
作(zuò)為(wèi)系列的(de)第一(y§₽'•ī)篇文(wén)章(zhāng),這(zhè)裡(lǐ)将著(zhe)重討(tǎo)論↓↕ ✘不(bù)涉及協議(yì)的(de)客戶端 ∑₩應用(yòng)程序網絡開(kāi)發。本系列文(wén)β 章(zhāng)将包括:
總的(de)來(lái)說(shuō),遊戲引σ €¶擎網絡支持是(shì)個(gè)非常大(dà)的(de)主題, ™≈因此本系列博文(wén)将圈定一(yī)個™★(gè)範圍——聚焦擁有(yǒ™&u)客戶端應用(yòng)程序的(de)遊戲,而不(bù)是≠♠£(shì)那(nà)些(xiē)基于browser-/AJAX的(de)遊戲> ,雖然這(zhè)兩種遊戲在設計(jì)上(shàng)有(yǒu)著(zheλα)很(hěn)多(duō)共同點,但(dàn)是(shì)其中的(dγ₽>e)區(qū)别也(yě)足夠讓討(tǎo)論分(fēn)≥₹δ開(kāi)。本系列博文(wén)将嘗試覆蓋遊戲網絡層開(kā✔¥→₩i)發的(de)常見(jiàn)理(lǐ)念®∞λ:
首先,不(bù)會(huì)隻聚焦某種類型的(de)遊戲,比如(rú)MMORP→∞↕Gs;毫無疑問(wèn),MMORPGs确δβ實在討(tǎo)論的(de)範疇中,但(dàn)是(shì)也(yě)不₩×↓(bù)乏社交遊戲、多(duō)玩(wán)家(jiā)戰略(包括實時(s≥✔hí)和(hé)回合制(zhì))、賭博類遊戲、證券交易型等等。而出人(r•εén)意料的(de)是(shì),在做(↕←πzuò)網絡支持時(shí),這(zhè)些(xiē)遊戲存在著(zhe)↕β☆¥大(dà)量的(de)共同點。(盡管許多(duō)取決于時(s♦₽☆♥hí)間(jiān)控制(zhì)問(wèn)題,這(zh&✔è)點将在Great TCP-v♠•s-UDP Debate一(yī)節詳述)。
其次,同樣不(bù)會(huì)限制(zhì)到(dào)某個(g↕♠è)特定的(de)平台:事(shì)實上(shàng),這(zhè)₹♣裡(lǐ)更推薦開(kāi)發者寫跨平台引擎,其中就(jiù)包含了(le £)網絡引擎。在實踐中,筆(bǐ)者也(yě)曾寫過一(yī)個(gè)網絡引擎'↕,它可(kě)以在5個(gè)以上(shλ✘↕←àng)完全不(bù)同的(de)平台上(shàng)運行(xíng),這(♣•★zhè)點将在第六條中進行(xíng)詳述。
再次,因為(wèi)基于遊戲引擎開(kāi)發者的(de)視(shì)角,"↓所以這(zhè)裡(lǐ)有(yǒu)個(g♦'è)背景是(shì)遊戲開(kāi)發者經常需要(yào)為(wèi)他(→×'✘tā)們的(de)遊戲開(kāi)發遊戲引擎。在>σ♦∏這(zhè)個(gè)情況下(xià),大(dà)多(duō)數(shù)♣€建議(yì)都(dōu)是(shì)适用(yòng)的(de)。
最後,雖然類似“哪個(gè)引擎或者網絡引擎是(shì)最好(h$≥ ǎo)的(de)?”這(zhè)樣的(de)®↓ 問(wèn)題已經超出了(le)討(tǎo)論的(de)範疇,但(d☆>↕♥àn)是(shì)本系列博文(wén)同 樣對(duì)回答(dá)這(zhè)個(gè)問(wèn)™¶題有(yǒu)所幫助;毫無疑問(wèn),答♣π(dá)案取決于遊戲的(de)具體(tǐ)需求,因此請(qǐng)詳細閱©$讀(dú)。換句話(huà)說(shuō):如(rú)果你₽(nǐ)的(de)遊戲引擎或者框架提供了(le)一(yī)個(gè)支∑ 撐網絡的(de)方式,這(zhè)些(xiē)博文(wén)可(kě)以作 <©£(zuò)為(wèi)一(yī)個(gè)工(gōng)具對(duì)其進行★☆♠(xíng)考量,從(cóng)而弄清其網±ε±絡實現(xiàn)是(shì)否對(duì)特®÷ε定的(de)遊戲有(yǒu)益。
OK,在交代完大(dà)緻的(de)討(tǎo)論方向後,下₹ (xià)面言歸正傳。
當下(xià),大(dà)多(duō)數(shù)客戶端UI框©'ε•架都(dōu)包含一(yī)個(gè)所謂的(de)“main&n☆σ§ bsp;thread”(或者叫“main ≠♦←★;loop”,運行(xíng)于“®αβ☆main thread”之中),而這(zhè™ )個(gè)“main thread&rd→≈& quo;本質上(shàng)會(huì)處理(lǐ)一(yī)些(xiē)€'特定的(de)事(shì)件(jiàn)(最原始的(de)是(s÷✔¥αhì)UI事(shì)件(jiàn))。這(zhè)種模型存在所有(yǒu)客¥"戶端框架之中,從(cóng)Windows&nbs←εp;GUI、Direct X和(hé)Cocoa,到(dào)Uni ✔ty 3D、Android和(₹→hé)iOS。同時(shí),也(yě)确 ↓實有(yǒu)一(yī)個(gè)很(hěn)好Ω÷↓(hǎo)的(de)理(lǐ)由來(lái)驅動大(dà)家≥(jiā)這(zhè)麽做(zuò):因為(wè<♥∞i)其他(tā)的(de)編程模型隻能(néng)給你(nǐ)帶來(lá★£i)噩夢。事(shì)實上(shàng),在≤↕♥♦實際工(gōng)作(zuò)中,筆(bǐ)者也(yě)隻碰到(dào)了(lα<e)一(yī)個(gè)“出格”的(de)框架,即→§≠最初Java的(de)AWT,而在AWT中編寫AP↕ σ→P的(de)痛苦也(yě)衆所周知(zhī×"&)(有(yǒu)鑒于此,AWT自(zì)始至終也(yě)沒有 σσ♥(yǒu)流行(xíng)起來(lái);實際上(shàng),谷歌(gē©£§∞)也(yě)确實需要(yào)為(wèi)Android開(kāi÷≈σ )發新的(de) GUI框架)。
那(nà)麽,在給應用(yòng)程序添加網絡支持後,事(shì ∞↕)件(jiàn)驅動模型究竟應該如(rú)何轉變?其實,這(zh✔©è)裡(lǐ)并不(bù)需要(yào)任何改變。實際生(shēng€")産中,所有(yǒu)遊戲網絡通(tōng)信邏輯都(dōu)由≠♦♣✔消息發送和(hé)接收構成;而每一(yī)個(εα>®gè)接收到(dào)的(de)網絡消息都(&€¥dōu)應該被作(zuò)為(wèi)遊戲事π(shì)件(jiàn)驅動邏輯(除去(qù)傳統的(d×≤e)UI事(shì)件(jiàn),比如(rú©λ¶")鼠标和(hé)鍵盤輸入)的(de)另一☆β(yī)個(gè)事(shì)件(jiàn)。通(tō∞♣>ng)常情況下(xià),這(zhè)個(gè)操作(zuò)可(kě★•±≥)以通(tōng)過給main thre∞δad的(de)“message queue'•∑”注入一(yī)條message輕±α≈松實現(xiàn)。舉個(gè)例子(zǐ),在Win32中,這(zhè∞♥'")個(gè)操作(zuò)通(tōng)常由PostMe♠✔ssage()或者PostThreadMessage()方法完 >成。如(rú)果你(nǐ)選擇的(de)圖形框架不(bù)支持這®<♦(zhè)個(gè)理(lǐ)念,你(nǐ)可(kě)能(néng)需要(≥>≥yào)通(tōng)過建立你(nǐ)的(de)隊φδ§•列并進行(xíng)輪詢進行(xíng)模拟(舉個(gè)例子(zǐ),Un ∞ity3D2012)。對(duì)比在單線程中強制(zhì)處理(lǐ)所有£ ¥≠(yǒu)事(shì)件(jiàn)(同時(shí)包含UI事(shì)件→✔"≠(jiàn)和(hé)網絡消息),将事(shì)件(jiàn)作(zuò)∑©為(wèi)數(shù)據(win32)還×π★(hái)是(shì)回調這(zhè)樣的(de)<α™ 問(wèn)題并不(bù)重要(yào)。NB:如(rú)果使用(δ♣yòng)Unity,這(zhè)個(gè)技(jì)巧很↓©(hěn)少(shǎo)會(huì)用(yòng)到(dào),因為(★↔wèi)Unity內(nèi)置的(de)網絡(已經使用(yε☆òng)了(le)Unity的(de)事(shλ'→ì)件(jiàn)處理(lǐ)線程)非常适用(©₩yòng)于“實時(shí)世界模拟(real-tim↓↕★e world simulato •r)”遊戲;然而根據具體(tǐ)遊戲特征,使用(yòn★∏× g)Unity網絡做(zuò)UDP傳輸也(♣•φ♠yě)并不(bù)一(yī)定就(jiù)是(shì)最好(hǎo)的¥ε(de)途徑——特别是(shì)那(>←≈'nà)些(xiē)與實時(shí)世界模拟無關的(de)遊戲。
在有(yǒu)些(xiē)用(yòng)例中,事(shì)件(←&₽Ωjiàn)處理(lǐ)線程可(kě)能(néng)與選擇框架的(de)× Ω“main thre ★ad”相(xiàng)去(qù)甚遠(y≈£®☆uǎn),但(dàn)是(shì)這(zhè)裡(lǐ)需要(↔≤¥™yào)謹記的(de)是(shì),将所有(yǒu)與邏輯相(xiàn ↓↔g)關事(shì)件(jiàn)處理(lǐ)都(dōu)放(fà£εng)到(dào)同一(yī)個(gè)單線程中。然而,純通(tōng)α♣信相(xiàng)關(與遊戲邏輯完全無關),比₩α★>如(rú)marshalling、en/decry↑∏•ption 和(hé) ♥δ(de)compres,可(kě)以(盡可(kě)能(néng))在&ldqu♠≠o;main thread&rd♦Ω∏quo;外(wài)部處理(lǐ),在下(xiΩ✘™à)面的(de)第3條中會(huì)詳細討(tǎo)論線程π₩♠隔離(lí)問(wèn)題。
猶記那(nà)年(nián),筆(bǐ)者還(hái)&ld×£↔quo;很(hěn)傻很(hěn)天真”,那(nà)時(shí)→ •★候負責給一(yī)個(gè)證券交易業(yèβ∑)務開(kāi)發網絡框架(PS:别問(wèn)我為(w≤'≥èi)什(shén)麽這(zhè)麽重要(yào)>∏σ©的(de)一(yī)個(gè)任務會(huì)&™交給一(yī)個(gè)沒經驗的(de)工(gōng)程師(shī),筆 <↔φ(bǐ)者同樣無解)。開(kāi)始的(de)時(shí×∏✘)候,新網絡庫編寫的(de)确實比較順利,但(δdàn)是(shì)在這(zhè)裡(l>☆↓♥ǐ),筆(bǐ)者同樣犯了(le)一(yī)個(gè)原則錯(c÷λ←uò)誤——在應用(yòng)程序層面調用(yòn∏βγg)了(le)一(yī)個(gè)回調(它本應該是(shì)1個£>(gè)回調來(lái)響應sendMessageOverTheNetwo"βrkAndCallbackOnReply"≠()-style函數(shù))。這(zhè)個(gè)蹩腳的(∑de)錯(cuò)誤曾一(yī)度給後續使用(yòn §'¥g)這(zhè)個(gè)框架的(de)同仁♣λ帶去(qù)了(le)大(dà)量麻煩。首先,交互(以及潛在的(de) ∞♦✔races)讓使用(yòng)它的(de)同事(shì)難以理(lǐ)解。∞"其次,給bugs和(hé)races追蹤帶來(lái)§π了(le)大(dà)量麻煩。最後,雖然并沒有(yǒu)太壞的(de)影(yǐn↓✔g)響,而且框架總體(tǐ)運行(xíng)良好(hǎo),但σ§ (dàn)是(shì)如(rú)果沒有(yǒu)這(γ₹∏zhè)個(gè)回調,開(kāi)發将變得(de)更加平順。
數(shù)年(nián)後,筆(bǐ)者一(yī•'®$)直為(wèi)大(dà)型多(duō)玩(w÷™ án)家(jiā)遊戲開(kāi)發網絡引擎—&md∞≈✘ash;同時(shí)在線玩(wán)家(₹¶✘αjiā)50萬,日(rì)消息數(shù)5億條。≥♣→而在吸取了(le)之前的(de)經驗後,避免了(le)類似線程回♦ ≠調,所有(yǒu)的(de)工(gōng)作(zuò)都(© dōu)井井有(yǒu)條,同時(shí)在≈π多(duō)平台切換上(shàng)也(yě)異常平順。
總結:如(rú)果你(nǐ)需要(yào)從(₩λ€∏cóng)網絡層實現(xiàn)一(yī)個(gè)回調到(dào)×"&應用(yòng)程序層,首先你(nǐ)需要(yào)将事∑↕∏≥(shì)件(jiàn)傳遞給事(shì)件≥∑÷✔(jiàn)處理(lǐ)線程(通(tōng)常情況下(xià)就(j♦₩iù)是(shì)main thread),随後通(tō↑✘£•ng)過網絡層庫調用(yòng)(發源于事(shì)件(ji δ→àn)處理(lǐ)線程)來(lái)處理≠∞•≠(lǐ)事(shì)件(jiàn),并在必要(yào)時(shí)調用(yβ₽↑←òng)應用(yòng)程序級回調。換句話(huà)說(shuō),下(x™β✔ià)面才是(shì)一(yī)個(gè)完善的(de)途徑:
network thread &nd$€δash;> inter-thread-co®"←mmunication &nd₩λash;> event-processing←©★ thread –>&nbs≠p;network-library-call &nd>¥δ©ash;> applicaλ↓tion-callback –>β; no-thread-sync-needed
而下(xià)面雖然可(kě)行(xíng),但(dàn)是(shìδ₹)不(bù)利于他(tā)人(rén)長(cháng)期使用(yòng)↔:
network thread –>§↔> network-library-call &nda÷♥sh;> applicat€α§↔ion-callback &n∞ ≈✘dash;> thread-sync-re♠&quired
在完善的(de)途徑中,回調隻存在事(shì)件(jiàn)處理(lǐ)線Ω↔§✔程環境中,這(zhè)将顯著簡化(huà)應用(yòng)程序開(k≥₽♠₽āi)發。所有(yǒu)應用(yòng)程序級處理(lǐ)都(dōu)被嚴格确≠<€ 定,從(cóng)而最大(dà)程度地(dì)減少(shǎo)races出現(<★xiàn)的(de)可(kě)能(néngφ∑±),同時(shí)也(yě)減少(shǎo)了(le)應用(yòng)€© 程序級所必要(yào)的(de)同步。上(shàng)面的(de)♣ →過程聽(tīng)起來(lái)可(kě)能(néng)比較笨重,操作(zu∏★→ò)起來(lái)也(yě)有(yǒu)些∞<(xiē)繁瑣,但(dàn)是(shì)它可(kě)以切實地(dì)減少(>♦shǎo)遊戲開(kāi)發者的(de)後續麻煩。
這(zhè)是(shì)網絡開(kāi)發者所有(y ₽ǒu)可(kě)以提交中影(yǐng)響"↔最大(dà)的(de)錯(cuò)誤之一(yσī)。如(rú)上(shàng)文(wén)所述,¶γ你(nǐ)需要(yào)在一(yī)個(gè)單獨的(de" )線程中處理(lǐ)所有(yǒu)事(shì)件(jiàn)。這(zhè)種<₹™操作(zuò)得(de)當且方便,但(dàn)麻煩也(yě±→×)因此産生(shēng),比如(rú):在一(yī)個(€λ gè)事(shì)件(jiàn)處理(lǐ)器(qì)中做(zuò)一™ε☆(yī)個(gè)簡單如(rú) ↑<;gethostbyname() 的(∞ de)調用(yòng),這(zhè)個(gè)操作(zuò)在小(xiǎo)範 ≥圍中不(bù)會(huì)存在任何問(wèn)題,但(dàn)是(shì&φ∑)在有(yǒu)些(xiē)情況中現(xiàn)實世界的(de)玩(wán)"↔★家(jiā)卻會(huì)因此阻塞數(shù)分(fēn)鐘(zhōng)≈λ☆♣之久!如(rú)果你(nǐ)在GUI線程中調用(yòng)這(zhè)樣一(yī)個(gè)函數(shù),對(d₹£uì)于用(yòng)戶來(lái)說(shuō),在函數(shù)阻塞時(π§₹÷shí),GUI一(yī)直都(dōu)處于frozeλ♠ n或者hanged狀态,這(zhè)從(cóng)用(yòng)戶體(tǐ)∞φ驗的(de)角度是(shì)絕對(duì)不(bù∞γ§ )允許的(de)。
因此,通(tōng)過GUI來(lái)做(zuò)網絡交互時(shí♠&)所有(yǒu)函數(shù)都(dōu)應該是(shì)非阻塞的(de),或♦φ者位于不(bù)同的(de)線程中。在這(zhè)種情況下(xi₹↔®à),你(nǐ)需要(yào)讓事(shì)件(jiàn) ∞••狀态機(jī)更加複雜(zá)(你(nǐ)可(kě)以效率地(↕<✘dì)取得(de)類似“waiting&nbs&Ω∑p;for DNS resolution&rd↕✔quo;這(zhè)樣的(de)狀态),同©≥¥δ時(shí)它還(hái)需要(yào)可(kě)以避免&ld±→×εquo;frozen”GUI ,并且可(kě)以讓你π$¥ (nǐ)處理(lǐ)網絡延時(shí),包括:
需要(yào)注意的(de)是(shì),這(zhè)點看(kàn)起∑>≈♦來(lái)似乎與第一(yī)條和(hé) ↑δ第二條相(xiàng)違背,但(dàn)事(s λhì)實上(shàng)并不(bù)是(shì)這(zhè)樣。對(duì)£>≠于“hey, soφ≥ should I do&n§∞↓÷bsp;it single-thr✔÷¥eaded or multi-§ threaded?”這(zhè)樣的(de)問(wèn)題,答(d±×♣≈á)案是(shì):系統級别網絡調用(yòng)要(yào)麽是 ' (shì)非阻塞的(de),要(yào)麽是(✘×shì)來(lái)自(zì)非事(shì)件(jiàn)處理(lǐβ≤<)線程;同時(shí),所有(yǒu)事(shì)件(jiàn)處理(lǐ)←¶←↑必須在事(shì)件(jiàn)處理(lǐ)線程中完成。這(★≤σzhè)就(jiù)意味著(zhe),如(rúε←)果使用(yòng)多(duō)線程,你(nǐ)需要(yào)在一<✔₩♠(yī)個(gè)非事(shì)件(jiàn)處理(lǐ)σ↓的(de)網絡處理(lǐ)線程中調用(yòng)類似阻塞≠∞←®recv()的(de)函數(shù),随後将調用(yòng)的(de)結果轉✔σ換為(wèi)一(yī)個(gè)事(shì)件(✔'←jiàn),并通(tōng)過隊列的(de)形式(如₽★•(rú)上(shàng)文(wén)1中介紹)将這(zhè)個(gè)事(™•φ≠shì)件(jiàn)傳遞給事(shì)件(j♦£•✘iàn)處理(lǐ)線程。嚴格來(lái)講,decryption/d©&₽♥ecompression就(jiù)要(yào) ♦進行(xíng)這(zhè)樣的(de)處理(lǐ),雖然需要(yào)去(₽≥¶λqù)做(zuò)避免事(shì)件(jiàn)處理(lǐ)線程成為(☆&£wèi)一(yī)個(gè)瓶頸的(de)流程,但(dàn)它通γ∏$β(tōng)常比隻将encryption/c©"≈↓ompression 扔到(dào)網絡處理★♥←(lǐ)線程中來(lái)得(de)更有(yǒu)性價比。
網絡線程的(de)另一(yī)個(gè)替代是(shì)nonδ♣-blocking IO,這(zhè)裡(lǐ)同樣存在一(yī¥ε$€)些(xiē)需要(yào)注意的(de)地(dì)方¥±(包括gethostbyname() §•£;和(hé)getaddrinfo()在主流平台中并不(®bù)存在non-blocking I☆₩O版本),同時(shí)筆(bǐ)者也(yě♣)不(bù)認為(wèi)在客戶端使用(yòng)non-blockinδ¥g帶來(lái)的(de)麻煩會(huì)更少(shǎo)。服務器(qì↕♠♥)端将是(shì)另一(yī)種情景,詳情會(h₩λ∏uì)在系列博文(wén)的(de)第三'÷φ₽部分(fēn)服務器(qì)端討(tǎo)論。
在遊戲引擎開(kāi)發中,很(hěn)多(duō)開(kāi)發者"∑✔使用(yòng)了(le)一(yī)個(gè)異常簡單的(de¥☆)網絡錯(cuò)誤處理(lǐ)途徑。也(yě)就(jiù₹ )是(shì),他(tā)們簡單的(de)将錯(cuò)誤抛到$↑© (dào)用(yòng)戶面前,隻留下(xià)一(•≥≥yī)句“服務器(qì)存在一(y♦&ī)點問(wèn)題,請(qǐng)重試”。這(zhè)個σ&(gè)做(zuò)法是(shì)非常討(tǎo)厭(yàn)的π"(de),并且不(bù)會(huì)帶來(lái)任何效果(當然輕松§§了(le)開(kāi)發者,但(dàn)是(shì)損害了(le)用(yòng☆♣)戶)。除下(xià)開(kāi)發人(rén)員(yuán♦ )太懶,不(bù)存在任何理(lǐ)由不(bù)将問(wè✘δγ<n)題在內(nèi)部解決。在問(wèn)題産生(shēng)π≥₹并給用(yòng)戶提示後,沒理(lǐ)由不(bù)自(zì)動重試而要(©∏φyào)求用(yòng)戶再次操作(zuò)。為(wèi)了(lε•e)通(tōng)知(zhī)這(zhè)個(gè)問(wèn)題,你∏↑♠"(nǐ)可(kě)以在屏幕的(de)顯著位置進行(xí∏<ng)顯示,或者是(shì)彈出一(yī)個(gè)對(duì)話(huà)ε≥框(沒有(yǒu)ok這(zhè)個(g'è)按鈕,隻有(yǒu)關閉),同時(shí)将在問(wèn) 題解決後自(zì)動消失。這(zhè)樣一(yī)來(lái),≥✔在問(wèn)題産生(shēng)用(yòng)戶離(lí)€開(kāi)後,如(rú)果你(nǐ)能(néng)短(d÷α¶uǎn)時(shí)間(jiān)解決問(wèn)題,你(nǐ)不(bù↓<)會(huì)對(duì)用(yòng)戶體(t×φφǐ)驗産生(shēng)任何影(yǐng)響。
有(yǒu)人(rén)可(kě)能(néng)争論不(bù)∑☆•停重試會(huì)造成網絡阻塞,但(dàn)是(shì)作(zuò)≥₩&為(wèi)一(yī)名開(kāi)發者,你(nǐ)有(yǒu)責≠♥ 任讓用(yòng)戶體(tǐ)驗變得(de)簡單。÷ $φ當然,你(nǐ)也(yě)可(kě)以設置一(yī)個(gè)臨界值,比如 →♠±(rú)5分(fēn)鐘(zhōng)來(lái)關閉重試,并提示&ldquo↕•;對(duì)不(bù)起,我們已經盡力了(le),但(d$♥±δàn)問(wèn)題在短(duǎn)時(shí)間(j©♣iān)內(nèi)無法得(de)到(dào) ¶™¶修複”。
綜合上(shàng)面的(de)1-3條,你(nǐ)通(tōng)常需要(yào)在網絡處理(lǐ)線程中檢測問(wèn♥→≥γ)題,并将它轉換成1個(gè)事(shì)件(jiàn),并在事(shì$ )件(jiàn)處理(lǐ)線程中處理(lǐ)事(≠αφshì)件(jiàn),比如(rú)顯示一(y•&δ≈ī)個(gè)對(duì)話(huà)框。
從(cóng)終端用(yòng)戶的(de φ•∏)角度來(lái)看(kàn),“網絡×>"π不(bù)可(kě)用(yòng)”、&ld"₩♥$quo;連接拒絕”以及“連接終止”沒有(y¥÷ǒu)任何區(qū)别;如(rú)果可(kě)能(né≠•'→ng)的(de)話(huà),你(nǐ)σ÷可(kě)能(néng)是(shì)想告訴他(tā)們網線未插入或者是(s₽ε↑¥hì)服務器(qì)故障或者是(shì)兩者之間(jiān)的(δ>>de)一(yī)些(xiē)問(wèn)題,但(dà€☆n)是(shì)僅僅因為(wèi)一(yī)些(xiē)專業(yè)用(yòn®g)語讓用(yòng)戶無法确定問(wèn)題¥≤←∞真相(xiàng)是(shì)完全不(bù)可(kě)取♦≤↑的(de)。更糟糕的(de)做(zuò)法是(shì),試圖将技(j ←ì)術(shù)細節隐藏于一(yī)些(xiē)模棱兩可(kě)的(de)話δ→(huà)語之間(jiān),比如(rú)“服務器(q±ì)有(yǒu)一(yī)點問(wèn)題§©∏”和(hé)“你(nǐ)丢失了(le)連接&↓αrdquo;。
總之,切記将錯(cuò)誤消息從(cóng)你 ♦↓(nǐ)能(néng)理(lǐ)解的(de€φ)語句轉換到(dào)用(yòng)戶能(n± βéng)理(lǐ)解的(de)提示,而不(bù)是(shì)讓用(yò≈≤¥ng)戶無法辨别各種提示間(jiān)的(•≈de)區(qū)别——讓所有(yǒu)消息看γ±(kàn)起來(lái)完全相(xiàn©∏★¥g)同。
縱觀當下(xià)遊戲領域,單平台遊戲已↑<¥經不(bù)再有(yǒu)吸引力。即使引擎隻為∏♣•β(wèi)一(yī)款遊戲打造,但(dànσ•↑)是(shì)你(nǐ)又(yòu)真的(d≈♣↓e)能(néng)确定遊戲未來(lái)不(bù)會(huì)過渡到ε★↑(dào)其他(tā)平台?實踐中,讓網絡δ≤→代碼跨平台并不(bù)是(shì)一(yīα<)件(jiàn)難事(shì),因此你(nǐ)沒理(lǐ)由不(bù)做(&✔ zuò)多(duō)平台的(de)準備。筆(bǐ)者個(gè)∞≈↕人(rén)的(de)網絡庫就(jiù)覆σ×蓋了(le)Windows、Linux、Mac Ω←λ;OS X、FreeBSD、iOS等引擎。Ω®α©
如(rú)果你(nǐ)的(de)遊戲引擎是(ε↑shì)基于C或者C++,并且将應用(yòng)程序α" 定義為(wèi)隻Windows平台,那(nà)麽就(jiù)可(kě)能(n ∏éng)嘗試一(yī)些(xiē)Windows特有(yǒu)的(de)函'"數(shù)(那(nà)些(xiē)以WSA*(≠₩)為(wèi)前綴的(de))來(lái₹$)通(tōng)信。請(qǐng)不(bù)要(yào)這(zhè)麽δ®♦做(zuò),轉而使用(yòng)Berkeley socket♥©s(那(nà)些(xiē)socket()/connect()/sπ ✘end()/recv()函數(shù))進行(xíng)取代;關于使&←用(yòng)細節,請(qǐng)自(zì)行(xíng)Google。對 ®(duì)于其他(tā)提供了(le)跨平台APIs的(de≈₩₹)編程語言,選擇一(yī)個(gè)合适的(de)網絡庫通(tō™δ<ng)常不(bù)會(huì)有(yǒu)太多(duō)問(wèn)題。$©
通(tōng)常情況下(xià),自(zì)動升級并不←εφ→(bù)會(huì)考慮為(wèi)遊戲引擎的(d♦§δe)一(yī)部分(fēn)。然而,個(≈•∞gè)人(rén)覺得(de)将自(zì)動升級納入網絡層會γ≠(huì)有(yǒu)一(yī)些(xiē)相(xiàng£₹∞☆)應的(de)好(hǎo)處,其原因是(shì):
上(shàng)面的(de)推理(lǐ)并不(bù)是(shì♠♠)在任何條件(jiàn)下(xià)都(dōu)成立的(deσ₽±≤),但(dàn)是(shì)我看(kàn)到(dào)了(le)®±類似系統的(de)實現(xiàn),同時(shí)也(yě)取得(de)✔≥≥了(le)非常好(hǎo)的(de)效果。
注意:盡管與網絡庫集成,你(nǐ)同樣需要(yàε§'o)在HTTP(而不(bù)是(shì)基于你(nǐ)的(de)協議☆↓α(yì))上(shàng)實現(xiàn)初始自(zì)動更新(會(h∞↕₹uì)在遊戲應用(yòng)啓動前啓動);™÷↔這(zhè)麽操作(zuò)并不(bù)會(huì)帶來(lái)✔±太多(duō)的(de)複雜(zá)性,但(σ♣φΩdàn)是(shì)很(hěn)可(kě)能(néng)↕ 會(huì)徹底地(dì)修改你(nǐ)的πΩπ(de)協議(yì)。
其他(tā)在啓動更新上(shàng)的(de)操作(zuò)是(shì)γδ♣∑非常複雜(zá)的(de),因此會(huì)單獨開(kāδΩi)一(yī)篇文(wén)章(zhāng)來(lái)表述
