• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Fork me on GitHub
            隨筆 - 215  文章 - 13  trackbacks - 0
            <2018年6月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567


            專(zhuān)注即時(shí)通訊及網(wǎng)游服務(wù)端編程
            ------------------------------------
            Openresty 官方模塊
            Openresty 標(biāo)準(zhǔn)模塊(Opm)
            Openresty 三方模塊
            ------------------------------------
            本博收藏大部分文章為轉(zhuǎn)載,并在文章開(kāi)頭給出了原文出處,如有再轉(zhuǎn),敬請(qǐng)保留相關(guān)信息,這是大家對(duì)原創(chuàng)作者勞動(dòng)成果的自覺(jué)尊重!!如為您帶來(lái)不便,請(qǐng)于本博下留言,謝謝配合。

            常用鏈接

            留言簿(1)

            隨筆分類(lèi)

            隨筆檔案

            相冊(cè)

            Awesome

            Blog

            Book

            GitHub

            Link

            搜索

            •  

            積分與排名

            • 積分 - 216763
            • 排名 - 118

            最新評(píng)論

            閱讀排行榜

            來(lái)自云風(fēng)大神:http://blog.codingnow.com/2017/04/mmorpg_client.html

            昨天和人閑扯,談到了 MMORPG 客戶(hù)端的網(wǎng)絡(luò)消息應(yīng)該基于怎樣的模型。依稀記得很早寫(xiě)過(guò)我的觀點(diǎn),但是 blog 上卻找不到。那么今天補(bǔ)上這么一篇吧。

            我認(rèn)為,MMO 類(lèi)游戲,服務(wù)器扮演的角色是虛擬的世界,一切的狀態(tài)變化都是在游戲服務(wù)器仲裁和演化的。而客戶(hù)端的角色本質(zhì)上是一個(gè)狀態(tài)呈現(xiàn)器,把玩家視角看到的虛擬世界的狀態(tài),通過(guò)網(wǎng)絡(luò)消息呈現(xiàn)出來(lái)。所以、在設(shè)計(jì)客戶(hù)端的網(wǎng)絡(luò)消息分發(fā)框架時(shí),應(yīng)圍繞這個(gè)職責(zé)來(lái)設(shè)計(jì)。

            客戶(hù)端發(fā)起的請(qǐng)求分兩種:一種是通知服務(wù)器,我扮演的角色狀態(tài)發(fā)生了改變,請(qǐng)求服務(wù)器仲裁;另一種是,我期望獲取服務(wù)器對(duì)象的最新?tīng)顟B(tài)。后一種有時(shí)以服務(wù)器主動(dòng)推送來(lái)解決,也可以用主動(dòng)請(qǐng)求,兩者主要的區(qū)別在于流量控制。

            其實(shí)、對(duì)于客戶(hù)端作為狀態(tài)呈現(xiàn)這個(gè)角色而言,請(qǐng)求和回應(yīng)之間的關(guān)系并沒(méi)有什么緊密聯(lián)系,并不適合使用基于 RPC 的網(wǎng)絡(luò)模型。這個(gè)無(wú)關(guān)乎 RPC 的實(shí)現(xiàn)是用 callback 還是用 coroutine 。

            這是因?yàn)椋?dāng)服務(wù)器的狀態(tài)改變時(shí),客戶(hù)端關(guān)心的應(yīng)該是這類(lèi)事情發(fā)生時(shí),我應(yīng)該如何呈現(xiàn);而不是具體到某個(gè)請(qǐng)求發(fā)出后,收到回應(yīng)我應(yīng)該怎么處理。RPC 把請(qǐng)求和回應(yīng)緊密耦合在一起,讓回應(yīng)的處理流程強(qiáng)依賴(lài)請(qǐng)求時(shí)的上下文,這樣容易引起不必要的狀態(tài)管理。

            比如,我看到我們公司的一個(gè)項(xiàng)目中曾經(jīng)出過(guò)這樣的 bug :UI 界面上點(diǎn)擊一個(gè)按鈕,用 callback 的形式發(fā)起了一次 RPC 調(diào)用;在回應(yīng)的 callback 函數(shù)中對(duì) UI 界面上的元素做了一系列的修改。可是在回應(yīng)的網(wǎng)絡(luò)消息收到時(shí), UI 界面已經(jīng)關(guān)閉了,由于處于節(jié)約內(nèi)存的考慮,還觸發(fā)了一些對(duì)象銷(xiāo)毀流程,結(jié)果因?yàn)椴倏夭淮嬖诘膶?duì)象造成了 bug 。

            你可以從別的角度來(lái)看待這個(gè) bug 。比如說(shuō)應(yīng)該建立一個(gè)更穩(wěn)固的 UI 框架,做更嚴(yán)謹(jǐn)?shù)纳诠芾怼5艺J(rèn)為,根源問(wèn)題就是沒(méi)有把請(qǐng)求和回應(yīng)解耦造成的。

            我們應(yīng)該這樣看待按鈕點(diǎn)擊事件:它只是觸發(fā)了一個(gè)事件在服務(wù)器上運(yùn)行,這個(gè)事件導(dǎo)致了某個(gè)服務(wù)器上的對(duì)象狀態(tài)改變了,而回應(yīng)包只是通知了狀態(tài)改變的結(jié)果。客戶(hù)端真正要做的是怎樣正確呈現(xiàn)這個(gè)結(jié)果。

            如果我們把客戶(hù)端處理網(wǎng)絡(luò)包的流程都?xì)w納成類(lèi)似的模型,統(tǒng)一成一個(gè)簡(jiǎn)單的框架就很容易了。

            客戶(hù)端根據(jù)收到的網(wǎng)絡(luò)包進(jìn)行相應(yīng)的處理,無(wú)論這個(gè)網(wǎng)絡(luò)包是服務(wù)器的推送、還是對(duì)之前客戶(hù)端發(fā)起請(qǐng)求的回應(yīng)。在這個(gè)框架下,只關(guān)心來(lái)了一個(gè)網(wǎng)絡(luò)包后的類(lèi)別,根據(jù)這個(gè)類(lèi)別來(lái)決定要做哪類(lèi)事情。處理流程是關(guān)聯(lián)在消息類(lèi)別上的,而不是關(guān)聯(lián)在單個(gè)請(qǐng)求上的。

            對(duì)于請(qǐng)求回應(yīng)的處理,其實(shí)和推送的處理并沒(méi)有本質(zhì)的不同。只是實(shí)現(xiàn)上略有差別。對(duì)應(yīng)回應(yīng)包的處理,處理流程得到的參數(shù)不僅僅是網(wǎng)絡(luò)包,還需要有對(duì)應(yīng)的請(qǐng)求數(shù)據(jù)(也就是客戶(hù)端當(dāng)初自己發(fā)起請(qǐng)求的參數(shù))和這個(gè)事件綁定的客戶(hù)端本地對(duì)象。

            通常我們會(huì)用一個(gè) session 號(hào)來(lái)關(guān)聯(lián)回應(yīng)包和請(qǐng)求包,在發(fā)起請(qǐng)求時(shí),不僅把請(qǐng)求內(nèi)容打包發(fā)給服務(wù)器,同時(shí)還把它記錄在本地,用 session 關(guān)聯(lián)起來(lái);這樣在收到請(qǐng)求時(shí),可以根據(jù) session 找回當(dāng)初請(qǐng)求的參數(shù),以及請(qǐng)求的類(lèi)型,這樣就可以不必讓服務(wù)器推送完整的狀態(tài)值,客戶(hù)端可以自己找到匹配的內(nèi)容。

            在大部分情況下,我們還需要在發(fā)起請(qǐng)求時(shí),給這個(gè) session 綁定一個(gè)本地的對(duì)象。雖然請(qǐng)求本身肯定有這個(gè)信息(否則服務(wù)器就不知道該請(qǐng)求到底操作呢什么東西),但額外的一個(gè)本地對(duì)象使用起來(lái)更方便,可以用來(lái)攜帶少量本地狀態(tài)信息。在回應(yīng)抵達(dá)時(shí),直接操作這個(gè)綁定對(duì)象寫(xiě)起來(lái)更方便。

            如果用 lua 來(lái)實(shí)現(xiàn),看起來(lái)大致是這樣的:

            send_request(obj, req_type, req_data) -- 發(fā)起一個(gè)請(qǐng)求,請(qǐng)求類(lèi)型為 req type ,參數(shù)是 req data ,綁定對(duì)象為 obj 。

            function net.req_type(obj, req_data, resp_data) -- 定義一個(gè)函數(shù)來(lái)處理 req_type 這種類(lèi)型的消息,可以獲得發(fā)起請(qǐng)求時(shí)的 obj 和 req data 以及服務(wù)器的回應(yīng) resp data 。

            posted on 2017-04-24 10:28 思月行云 閱讀(589) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): MMO
            亚洲乱亚洲乱淫久久| 久久受www免费人成_看片中文| 性欧美丰满熟妇XXXX性久久久 | 婷婷综合久久狠狠色99h| 久久99精品久久久久久| 精品久久久久久国产三级| 久久精品成人| 久久天天躁狠狠躁夜夜躁2O2O| 久久777国产线看观看精品| 思思久久99热免费精品6| 国产成人精品综合久久久久 | 久久久久久久久无码精品亚洲日韩| 久久久久久久99精品免费观看| 亚洲精品99久久久久中文字幕| 国产99精品久久| 国产亚洲精品久久久久秋霞 | 国产精品一区二区久久国产| 久久久久免费视频| 国产精品久久久久无码av| 久久99久国产麻精品66| 国内精品久久久久久久影视麻豆| 久久亚洲春色中文字幕久久久| 无码精品久久一区二区三区 | 久久精品一本到99热免费| 久久99精品国产麻豆婷婷| a高清免费毛片久久| 亚洲综合精品香蕉久久网| 久久久久久国产a免费观看黄色大片| 7777久久亚洲中文字幕| 久久亚洲美女精品国产精品| 精品国产99久久久久久麻豆 | 久久免费大片| 亚洲AV伊人久久青青草原| 久久精品亚洲福利| 内射无码专区久久亚洲| 久久精品中文字幕有码| 久久精品成人免费国产片小草| 精品久久久久久国产三级| 欧美午夜精品久久久久久浪潮| 久久伊人五月天论坛| 亚洲欧美另类日本久久国产真实乱对白|