freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

游戲服務(wù)器架構(gòu)-資料下載頁

2024-10-13 20:02本頁面
  

【正文】 整理,大概的代碼會類似這樣:狀態(tài)基類接口:StateBase{void Enter()= 0。void Leave()= 0。void Process(Message* msg)= 0。}。狀態(tài)機(jī)基類接口:MachineBase{void ChangeState(StateBase* state)= 0。StateBase* m_curState。}。我們的邏輯處理類會從MachineBase派生,當(dāng)取出數(shù)據(jù)包后交給當(dāng)前狀態(tài)處理,前面描述的兩個狀態(tài)類從StateBase派生,每個狀態(tài)類只處理該狀態(tài)標(biāo)識下需要處理的消息。當(dāng)要進(jìn)行狀態(tài)轉(zhuǎn)換時,調(diào)用MachineBase的ChangeState()方法,顯示地告訴狀態(tài)機(jī)管理類自己要轉(zhuǎn)到哪一個狀態(tài)。所以,狀態(tài)類內(nèi)部需要保存狀態(tài)機(jī)管理類的指針,這個可以在狀態(tài)類初始化時傳入。具體的實(shí)現(xiàn)細(xì)節(jié)就不做過多描述了。使用狀態(tài)機(jī)雖然避免了復(fù)雜的判斷語句,但也引入了新的麻煩。當(dāng)我們在進(jìn)行狀態(tài)轉(zhuǎn)換時,可能會需要將一些現(xiàn)場數(shù)據(jù)從老狀態(tài)對象轉(zhuǎn)移到新狀態(tài)對象,這需要在定義接口時做一下考慮。如果不希望執(zhí)行拷貝,那么這里公有的現(xiàn)場數(shù)據(jù)也可放到狀態(tài)機(jī)類中,只是這樣在使用時可能就不那么優(yōu)雅了。BR正如同在設(shè)計(jì)模式中所描述的,所有的模式都是已有問題的另一種解決方案,也就是說這并不是唯一的解決方案。放到我們今天討論的State模式中,就拿登錄服所處理的兩個狀態(tài)來說,也許用mangos所采用的遍歷處理函數(shù)的方法可能更簡單,但當(dāng)系統(tǒng)中的狀態(tài)數(shù)量增多,狀態(tài)標(biāo)識也變多的時候,State模式就顯得尤其重要了。比如在游戲服務(wù)器上玩家的狀態(tài)管理,還有在實(shí)現(xiàn)NPC人工智能時的各種狀態(tài)管理,這些就留作以后的專題吧。服務(wù)器公共組件事件與信號關(guān)于這一節(jié),這幾天已經(jīng)打了好幾遍草稿,總覺得說不清楚,也不好組織這些內(nèi)容,但是打鐵要趁熱,為避免熱情消退,先整理一點(diǎn)東西放這,好繼續(xù)下面的主題,以后如果有機(jī)會再回來完善吧。本節(jié)內(nèi)容欠考慮,希望大家多給點(diǎn)意見。有些類似于QT中的event與signal,我將一些動作請求消息定義為事件,而將狀態(tài)改變消息定義為信號。比如在QT應(yīng)用程序中,用戶的一次鼠標(biāo)點(diǎn)擊會產(chǎn)生一個鼠標(biāo)點(diǎn)擊事件加入到事件隊(duì)列中,當(dāng)處理此事件時可能會導(dǎo)致某個按鈕控件產(chǎn)生一個clicked()信號。對應(yīng)到我們的服務(wù)器上的一個例子,玩家登錄時會發(fā)給服務(wù)器一個請求登錄的數(shù)據(jù)包,服務(wù)器可將其當(dāng)作一個用戶登錄事件,該事件處理完后可能會產(chǎn)生一個用戶已登錄信號。這樣,與QT類似,對于事件我們可以重定義其處理方法,甚至過濾掉某些事件使其不被處理,但對于信號我們只是收到了一個通知,有些類似于Observe模式中的觀察者,當(dāng)收到更新通知時,我們只能更新自己的狀態(tài),對剛剛發(fā)生的事件我不已不能做任何影響。仔細(xì)來看,事件與信號其實(shí)并無多大差別,從我們對其需求上來說,都只要能注冊事件或信號響應(yīng)函數(shù),在事件或信號產(chǎn)生時能夠被通知到即可。但有一項(xiàng)區(qū)別在于,事件處理函數(shù)的返回值是有意義的,我們要根據(jù)這個返回值來確定是否還要繼續(xù)事件的處理,比如在QT中,事件處理函數(shù)如果返回true,則這個事件處理已完成,QApplication會接著處理下一個事件,而如果返回false,那么事件分派函數(shù)會繼續(xù)向上尋找下一個可以處理該事件的注冊方法。信號處理函數(shù)的返回值對信號分派器來說是無意義的。簡單點(diǎn)說,就是我們可以為事件定義過濾器,使得事件可以被過濾。這一功能需求在游戲服務(wù)器上是到處存在的。關(guān)于事件和信號機(jī)制的實(shí)現(xiàn),網(wǎng)絡(luò)上的開源訓(xùn)也比較多,比如FastDelegate,sigslot,boost::signal等,其中sigslot還被Google采用,在libjingle的代碼中我們可以看到他是如何被使用的。在實(shí)現(xiàn)事件和信號機(jī)制時或許可以考慮用同一套實(shí)現(xiàn),在前面我們就分析過,兩者唯一的區(qū)別僅在于返回值的處理上。另外還有一個需要我們關(guān)注的問題是事件和信號處理時的優(yōu)先級問題。在QT中,事件因?yàn)槎际桥c窗口相關(guān)的,所以事件回調(diào)時都是從當(dāng)前窗口開始,一級一級向上派發(fā),直到有一個窗口返回true,截?cái)嗔耸录奶幚頌橹?。對于信號的處理則比較簡單,默認(rèn)是沒有順序的,如果需要明確的順序,可以在信號注冊時顯示地指明槽的位置。在我們的需求中,因?yàn)闆]有窗口的概念,事件的處理也與信號類似,對注冊過的處理器要按某個順序依次回調(diào),所以優(yōu)先級的設(shè)置功能是需要的。最后需要我們考慮的是事件和信號的處理方式。在QT中,事件使用了一個事件隊(duì)列來維護(hù),如果事件的處理中又產(chǎn)生了新的事件,那么新的事件會加入到隊(duì)列尾,直到當(dāng)前事件處理完畢后,QApplication再去隊(duì)列頭取下一個事件來處理。而信號的處理方式有些不同,信號處理是立即回調(diào)的,也就是一個信號產(chǎn)生后,他上面所注冊的所有槽都會立即被回調(diào)。這樣就會產(chǎn)生一個遞歸調(diào)用的問題,比如某個信號處理器中又產(chǎn)生了一個信號,會使得信號的處理像一棵樹一樣的展開。我們需要注意的一個很重要的問題是會不會引起循環(huán)調(diào)用。關(guān)于事件機(jī)制的考慮其實(shí)還很多,但都是一些不成熟的想法。在上面的文字中就同時出現(xiàn)了消息、事件和信號三個相近的概念,而在實(shí)際處理中,經(jīng)常發(fā)現(xiàn)三者不知道如何界定的情況,實(shí)際的情況比我在這里描述的要混亂的多。這里也就當(dāng)是挖下一個坑,希望能夠有所交流。再談登錄服的實(shí)現(xiàn)離我們的登錄服實(shí)現(xiàn)已經(jīng)太遠(yuǎn)了,先拉回來一下。關(guān)于登錄服、大區(qū)服及游戲世界服的結(jié)構(gòu)之前已做過探討,這里再把各自的職責(zé)和關(guān)系列一下。GateWay/WorldServer GateWay/WodlServer LoginServer LoginServer DNSServer WorldServerMgr | | | | | | | | internet | clients其中DNSServer負(fù)責(zé)帶負(fù)載均衡的域名解析服務(wù),返回LoginServer的IP地址給客戶端。WorldServerMgr維護(hù)當(dāng)前大區(qū)內(nèi)的世界服列表,LoginServer會從這里取世界列表發(fā)給客戶端。LoginServer處理玩家的登錄及世界服選擇請求。GateWay/WorldServer為各個獨(dú)立的世界服或者通過網(wǎng)關(guān)連接到后面的世界服。在mangos的代碼中,我們注意到登錄服是從數(shù)據(jù)庫中取的世界列表,而在wow官方服務(wù)器中,我們卻會注意到,這個世界服列表并不是一開始就固定,而是動態(tài)生成的。當(dāng)每周一次的維護(hù)完成之后,我們可以很明顯的看到這個列表生成的過程。剛開始時,世界列表是空的,慢慢的,世界服會一個個加入進(jìn)來,而這里如果有世界服當(dāng)機(jī),他會顯示為離線,不會從列表中刪除。但是當(dāng)下一次服務(wù)器再維護(hù)后,所有的世界服都不存在了,全部重新開始添加。從上面的過程描述中,我們很容易想到利用一個臨時的列表來保存世界服信息,這也是我們增加WorldServerMgr服務(wù)器的目的所在。GateWay/WorldServer在啟動時會自動向WorldServerMgr注冊自己,這樣就把自己所代表的游戲世界添加到世界列表中了。類似的,如果DNSServer也可以讓LoginServer自己去注冊,這樣在臨時LoginServer時就不需要去改動DNSServer的配置文件了。WorldServerMgr內(nèi)部的實(shí)現(xiàn)很簡單,監(jiān)聽一個固定的端口,接受來自WorldServer的主動連接,并檢測其狀態(tài)。這里可以用一個心跳包來實(shí)現(xiàn)其狀態(tài)的檢測,如果WorldServer的連接斷開或者在規(guī)定時間內(nèi)未收到心跳包,則將其狀態(tài)更新為離線。另外WorldServerMgr還處理來自LoginServer的列表請求。由于世界列表并不常變化,所以LoginServer沒有必要每次發(fā)送世界列表時都到WorldServerMgr上去取,LoginServer完全可以自己維護(hù)一個列表,當(dāng)WorldServerMgr上的列表發(fā)生變化時,WorldServerMgr會主動通知所有的LoginServer也更新一下自己的列表。這個或許就可以用前面描述過的事件方式,或者就是觀察者模式了。WorldServerMgr實(shí)現(xiàn)所要考慮的內(nèi)容就這些,我們再來看看LoginServer,這才是我們今天要重點(diǎn)討論的對象。前面探討一些服務(wù)器公共組件,那我們這里也應(yīng)該試用一下,不能只是停留在理論上。先從狀態(tài)機(jī)開始,前面也說過了,登錄服上的連接會有兩種狀態(tài),一是帳號密碼驗(yàn)證狀態(tài),一是服務(wù)器列表選擇狀態(tài),其實(shí)還有另外一個狀態(tài)我們未曾討論過,因?yàn)樗c我們的登錄過程并無多大關(guān)系,這就是升級包發(fā)送狀態(tài)。三個狀態(tài)的轉(zhuǎn)換流程大致為:LogonState驗(yàn)證成功版本檢查版本低于最新值轉(zhuǎn)到UpdateState |版本等于最新值轉(zhuǎn)到WorldState這個版本檢查的和決定下一個狀態(tài)的過程是在LogonState中進(jìn)行的,下一個狀態(tài)的選擇是由當(dāng)前狀態(tài)來決定。密碼驗(yàn)證的過程使用了SRP6協(xié)議,具體過程就不多做描述,每個游戲使用的方式也都不大一樣。而版本檢查的過程就更無值得探討的東西,一個ifelse即可。升級狀態(tài)其實(shí)就是文件傳輸過程,文件發(fā)送完畢后通知客戶端開始執(zhí)行升級文件并關(guān)閉連接。世界選擇狀態(tài)則提供了一個列表給客戶端,其中包括了所有游戲世界網(wǎng)關(guān)服務(wù)器的IP、PORT和當(dāng)前負(fù)載情況。如果客戶端一直連接著,則該狀態(tài)會以每5秒一次的頻率不停刷新列表給客戶端,當(dāng)然是否值得這樣做還是有待商榷。整個過程似乎都沒有值得探討的內(nèi)容,但是,還沒有完。當(dāng)客戶端選擇了一個世界之后該怎么辦?wow的做法是,當(dāng)客戶端選擇一個游戲世界時,客戶端會主動去連接該世界服的IP和PORT,然后進(jìn)入這個游戲世界。與此同時,與登錄服的連接還沒有斷開,直到客戶端確實(shí)連接上了選定的世界服并且走完了排隊(duì)過程為止。這是一個很必要的設(shè)計(jì),保證了我們在因意外情況連接不上世界服或者發(fā)現(xiàn)世界服正在排隊(duì)而想換另外一個試試時不會需要重新進(jìn)行密碼驗(yàn)證。但是我們所要關(guān)注的還不是這些,而是客戶端去連接游戲世界的網(wǎng)關(guān)服時服務(wù)器該如何識別我們。打個比方,有個不自覺的玩家不遵守游戲規(guī)則,沒有去驗(yàn)證帳號密碼就直接跑去連接世界服了,就如同一個不自覺的乘客沒有換登機(jī)牌就直接跑到登機(jī)口一樣。這時,乘務(wù)員會客氣地告訴你要先換登機(jī)牌,那登機(jī)牌又從哪來?檢票口換的,人家會先驗(yàn)明你的身份,確認(rèn)后才會發(fā)給你登機(jī)牌。一樣的處理過程,我們的登錄服在驗(yàn)明客戶端身份后,也會發(fā)給客戶端一個登機(jī)牌,這個登機(jī)牌還有一個學(xué)名,叫做session key。客戶端拿著這個session key去世界服網(wǎng)關(guān)處就可正確登錄了嗎?似乎還是有個疑問,他怎么知道我這個key是不是造假的?沒辦法,中國的假貨太多,我們不得不到處都考慮假貨的問題。方法很簡單,去找給他登機(jī)牌的那個檢票員問一下,這張牌是不是他發(fā)的不就得了。可是,那么多的LoginServer,要一個個問下來,這效率也太低了,后面排的長隊(duì)一定會開始叫喚了。那么,LoginServer將這個key存到數(shù)據(jù)庫中,讓網(wǎng)關(guān)服自己去數(shù)據(jù)庫驗(yàn)證?似乎也是個可行的方案。如果覺得這樣給數(shù)據(jù)庫帶來了太大的壓力的話,也可以考慮類似WorldServerMgr的做法,用一個臨時的列表來保存,甚至可以將這個列表就保存到WorldServerMgr上,他正好是全區(qū)唯一的。這兩種方案的本質(zhì)并無差別,只是看你愿意將負(fù)載放在哪里。而不管在哪里,這個查詢的壓力都是有點(diǎn)大的,想想,全區(qū)所有玩家呢。所以,我們也可以試著考慮一種新的方案,一種不需要去全區(qū)唯一一個入口查詢的方案。那我們將這些session key分開存儲不就得了。一個可行的方案是,讓任意時刻只有一個地方保存一個客戶端的session key,這個地方可能是客戶端當(dāng)前正連接著的服務(wù)器,也可以是它正要去連接的服務(wù)器。讓我們來詳細(xì)描述一下這個過程,客戶端在LoginServer上驗(yàn)證通過時,LoginServer為其生成了本次會話的session key,但只是保存在當(dāng)前的LoginServer上,不會存數(shù)據(jù)庫,也不會發(fā)送給WorldServerMgr。如果客戶端這時想要去某個游戲世界,那么他必須先通知當(dāng)前連接的LoginServer要去的服務(wù)器地址,LoginServer將session key安全轉(zhuǎn)移給目標(biāo)服務(wù)器,轉(zhuǎn)移的意思是要確保目標(biāo)服務(wù)器收到了session key,本地保存的要刪除掉。轉(zhuǎn)移成功后LoginServer通知客戶端再去連接目標(biāo)服務(wù)器,這時目標(biāo)服務(wù)器在驗(yàn)證session key合法性的時候就不需要去別處查詢了,只在本地保存的session key列表中查詢即可。當(dāng)然了,為了session key的安全,所有的服務(wù)器在收到一個新的session key后都會為其設(shè)一個有效期,在有效期過后還沒來認(rèn)證的,則該session key會被自動刪除。同時,所有服務(wù)器上的session key在連接關(guān)閉后一定會被刪除,保證一個session key真正只為一次連接會話服務(wù)。但是,很顯然的,wow并沒有采用這種方案,因?yàn)榭蛻舳嗽谶x擇世界服時并沒有向服務(wù)器發(fā)送要求確認(rèn)的消息。wow中的session key應(yīng)該是保存在一個類似于WorldServerMgr的地方,或者如mangos一樣,就是保存在了數(shù)據(jù)庫中。不管是怎樣一種方式,了解了其過程,代碼實(shí)現(xiàn)都是比較簡單的,我們就不再贅述了第四篇:游戲架構(gòu)設(shè)計(jì)淺談游戲策劃的前期工作班級:09數(shù)字媒體技術(shù)姓名:廖偉民學(xué)號:090804006摘要:游戲制作所涉及的知識領(lǐng)域極其廣泛,其中就單其游戲策劃這一塊就涉及到三大內(nèi)容:前期的準(zhǔn)備工作、中期的制作工作、后期的宣傳工作。因此作為個人沒時間也不可能對每一區(qū)域都了解。在這篇文章當(dāng)中我將針對游戲策劃當(dāng)中的前期準(zhǔn)備進(jìn)行說明,并發(fā)表自己的看法。關(guān)鍵字:可行性、調(diào)研、工作計(jì)劃、草案引言:不少人認(rèn)為游戲策劃就是寫個精彩的故事出幾個好點(diǎn)子,如果事情如此簡單那不是每個人都可以做策劃?由于國內(nèi)的游戲制作業(yè)剛剛起步,既缺乏系統(tǒng)的專業(yè)理論指導(dǎo),又缺乏實(shí)戰(zhàn)經(jīng)驗(yàn),以至大多數(shù)玩家甚至一些游戲制作公司在對待策劃這個問題上都明顯存在不少誤區(qū)[1]。其實(shí)每一個游戲的策劃都要經(jīng)歷很多步驟和過程,就游戲策劃的前期準(zhǔn)備工作當(dāng)中就包含了對技術(shù)、經(jīng)濟(jì)、人力資源這三點(diǎn)的可行性分析,市場調(diào)研,確定工作計(jì)劃以及撰寫策劃草案這四個步驟,下面我將對其一一經(jīng)行分
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評公示相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1