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

正文內(nèi)容

游戲服務(wù)器架構(gòu)(文件)

2025-10-10 20:02 上一頁面

下一頁面
 

【正文】 程,那外掛制作者總有辦法知道我們的加密過程,所以,這個方法仍不夠安全。噢,不要管那個王小云的什么論文,如果我真有那么好的運(yùn)氣,早中500w了,還用在這考慮該死的服務(wù)器設(shè)計(jì)嗎?似乎是一個很完美的方案,外掛制作者再也偷不到我們的密碼了。很幸運(yùn)的是,偉大的數(shù)學(xué)字們早就為我們準(zhǔn)備好了很多優(yōu)秀的這類算法,而且經(jīng)理論和實(shí)踐都證明他們也確實(shí)是足夠安全的。不過其代碼實(shí)現(xiàn)步驟倒是并不復(fù)雜,mangos中的代碼也還算清晰,我們也不再贅述。登錄服將從大區(qū)服上獲取到的游戲世界列表發(fā)給已驗(yàn)證通過的客戶端即可。服務(wù)器公共組件實(shí)現(xiàn)mangos的游戲主循環(huán)當(dāng)閱讀一項(xiàng)工程的源碼時,我們大概會選擇從main函數(shù)開始,而當(dāng)開始一項(xiàng)新的工程時,第一個寫下的函數(shù)大多也是main。mangos的登錄服是一個單線程的結(jié)構(gòu),雖然在數(shù)據(jù)庫連接中可以開啟一個獨(dú)立的線程,但這個線程也只是對無返回結(jié)果的執(zhí)行類SQL做緩沖,而對需要有返回結(jié)果的查詢類SQL還是在主邏輯線程中阻塞調(diào)用的。很簡單的結(jié)構(gòu),也比較容易理解。另外,在服務(wù)器實(shí)現(xiàn)上,網(wǎng)絡(luò)IO與邏輯處理一般會放在不同的線程中,以免耗時較長的IO過程阻塞住了需要立即反應(yīng)的游戲邏輯。正如我們曾討論過的,為了游戲主邏輯循環(huán)的流暢運(yùn)行,所有比較耗時的IO操作都會分享到單獨(dú)的線程中去做,如網(wǎng)絡(luò)IO,數(shù)據(jù)庫IO和日志IO等。這個循環(huán)將一直持續(xù),直到收到一個通知服務(wù)器關(guān)閉的消息包。}這里就有一個問題需要探討了,在getMessage()的時候,我們應(yīng)該去哪里取消息?前面我們考慮過,至少會有三個消息來源,而我們還討論過,這些消息源的IO操作都是在獨(dú)立的線程中進(jìn)行的,我們這里的主線程不應(yīng)該直接去那幾處消息源進(jìn)行阻塞式的IO操作。Message* getMessage()。我們所能想到的最簡單的消息隊(duì)列可能就是使用stl的list來實(shí)現(xiàn)了,即消息隊(duì)列內(nèi)部維護(hù)一個list和一個互斥鎖,putMessage時將message加入到隊(duì)列尾,getMessage時從隊(duì)列頭取一個message返回,同時在getMessage和putMessage之前都要求先獲取鎖資源。提供一個隊(duì)列容器,里面有多個隊(duì)列,每個隊(duì)列都可固定存放一定數(shù)量的消息。這里為每個隊(duì)列設(shè)了個最大消息數(shù),看來好像是打算只有當(dāng)IO線程寫滿隊(duì)列時才會將其放回到容器中換另一個隊(duì)列。兩個隊(duì)列,一個給邏輯線程讀,一個給IO線程用來寫,當(dāng)邏輯線程讀完隊(duì)列后會將自己的隊(duì)列與IO線程的隊(duì)列相調(diào)換。兩種方案都是很優(yōu)秀的優(yōu)化方案,但也都是有其適用范圍的。頻繁的內(nèi)存分配不但增加了系統(tǒng)開銷,更使得內(nèi)存碎片不斷增多,非常不利于我們的服務(wù)器長期穩(wěn)定運(yùn)行。如果追上了怎么辦?那就是沒有數(shù)據(jù)可讀了,先等會兒唄,等跑的人向前跑幾步了再追,總不能讓游戲沒得玩了吧。也就是,大家都得遵守規(guī)定,追的人不能從桌子上跨過去,跑的人當(dāng)然也不允許反過來跑。在解包及解密完成后,我們會將這個數(shù)據(jù)包復(fù)制到邏輯線程消息隊(duì)列中,如果我們只使用一個隊(duì)列,那這里也將會是個環(huán)形緩沖區(qū),IO線程往里寫,邏輯線程在后面讀,互相追逐。服務(wù)器公共組件實(shí)現(xiàn)發(fā)包的方式前面一直都在說接收數(shù)據(jù)時的處理方法,我們應(yīng)該用專門的IO線程,接收到完整的消息包后加入到主線程的消息隊(duì)列,但是主線程如何發(fā)送數(shù)據(jù)還沒有探討過??紤]數(shù)據(jù)緩存的話,那這里這可以有兩種實(shí)現(xiàn)方式了,一是為每個玩家準(zhǔn)備一個緩沖區(qū),另外就是只有一個全局的緩沖區(qū),要發(fā)送的數(shù)據(jù)加入到全局緩沖區(qū)的時候同時要指明這個數(shù)據(jù)是發(fā)到哪個socket的。有關(guān)該優(yōu)化的說明在云風(fēng)描述其連接服務(wù)器實(shí)現(xiàn)的blog文章中也有講到,有興趣的可以去閱讀一下。bool(AuthSocket::*handler)(void)。而這個狀態(tài)標(biāo)識的改變是在運(yùn)行時進(jìn)行的,確切的說是在收到某個消息并正確處理完后改變的。由于這里的兩個狀態(tài)標(biāo)識只區(qū)分出了兩種狀態(tài),所以,我們僅需要兩個獨(dú)立的類,用以表示兩種狀態(tài)即可。void Process(Message* msg)= 0。}。具體的實(shí)現(xiàn)細(xì)節(jié)就不做過多描述了。BR正如同在設(shè)計(jì)模式中所描述的,所有的模式都是已有問題的另一種解決方案,也就是說這并不是唯一的解決方案。本節(jié)內(nèi)容欠考慮,希望大家多給點(diǎn)意見。這樣,與QT類似,對于事件我們可以重定義其處理方法,甚至過濾掉某些事件使其不被處理,但對于信號我們只是收到了一個通知,有些類似于Observe模式中的觀察者,當(dāng)收到更新通知時,我們只能更新自己的狀態(tài),對剛剛發(fā)生的事件我不已不能做任何影響。簡單點(diǎn)說,就是我們可以為事件定義過濾器,使得事件可以被過濾。另外還有一個需要我們關(guān)注的問題是事件和信號處理時的優(yōu)先級問題。最后需要我們考慮的是事件和信號的處理方式。我們需要注意的一個很重要的問題是會不會引起循環(huán)調(diào)用。再談登錄服的實(shí)現(xiàn)離我們的登錄服實(shí)現(xiàn)已經(jīng)太遠(yuǎn)了,先拉回來一下。LoginServer處理玩家的登錄及世界服選擇請求。剛開始時,世界列表是空的,慢慢的,世界服會一個個加入進(jìn)來,而這里如果有世界服當(dāng)機(jī),他會顯示為離線,不會從列表中刪除。類似的,如果DNSServer也可以讓LoginServer自己去注冊,這樣在臨時LoginServer時就不需要去改動DNSServer的配置文件了。由于世界列表并不常變化,所以LoginServer沒有必要每次發(fā)送世界列表時都到WorldServerMgr上去取,LoginServer完全可以自己維護(hù)一個列表,當(dāng)WorldServerMgr上的列表發(fā)生變化時,WorldServerMgr會主動通知所有的LoginServer也更新一下自己的列表。先從狀態(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)其實(shí)就是文件傳輸過程,文件發(fā)送完畢后通知客戶端開始執(zhí)行升級文件并關(guān)閉連接。當(dāng)客戶端選擇了一個世界之后該怎么辦?wow的做法是,當(dāng)客戶端選擇一個游戲世界時,客戶端會主動去連接該世界服的IP和PORT,然后進(jìn)入這個游戲世界。打個比方,有個不自覺的玩家不遵守游戲規(guī)則,沒有去驗(yàn)證帳號密碼就直接跑去連接世界服了,就如同一個不自覺的乘客沒有換登機(jī)牌就直接跑到登機(jī)口一樣。方法很簡單,去找給他登機(jī)牌的那個檢票員問一下,這張牌是不是他發(fā)的不就得了。這兩種方案的本質(zhì)并無差別,只是看你愿意將負(fù)載放在哪里。一個可行的方案是,讓任意時刻只有一個地方保存一個客戶端的session key,這個地方可能是客戶端當(dāng)前正連接著的服務(wù)器,也可以是它正要去連接的服務(wù)器。當(dāng)然了,為了session key的安全,所有的服務(wù)器在收到一個新的session key后都會為其設(shè)一個有效期,在有效期過后還沒來認(rèn)證的,則該session key會被自動刪除。不管是怎樣一種方式,了解了其過程,代碼實(shí)現(xiàn)都是比較簡單的,我們就不再贅述了第四篇:游戲架構(gòu)設(shè)計(jì)淺談游戲策劃的前期工作班級:09數(shù)字媒體技術(shù)姓名:廖偉民學(xué)號:090804006摘要:游戲制作所涉及的知識領(lǐng)域極其廣泛,其中就單其游戲策劃這一塊就涉及到三大內(nèi)容:前期的準(zhǔn)備工作、中期的制作工作、后期的宣傳工作。其實(shí)每一個游戲的策劃都要經(jīng)歷很多步驟和過程,就游戲策劃的前期準(zhǔn)備工作當(dāng)中就包含了對技術(shù)、經(jīng)濟(jì)、人力資源這三點(diǎn)的可行性分析,市場調(diào)研,確定工作計(jì)劃以及撰寫策劃草案這四個步驟,下面我將對其一一經(jīng)行分析。在這篇文章當(dāng)中我將針對游戲策劃當(dāng)中的前期準(zhǔn)備進(jìn)行說明,并發(fā)表自己的看法。但是,很顯然的,wow并沒有采用這種方案,因?yàn)榭蛻舳嗽谶x擇世界服時并沒有向服務(wù)器發(fā)送要求確認(rèn)的消息。如果客戶端這時想要去某個游戲世界,那么他必須先通知當(dāng)前連接的LoginServer要去的服務(wù)器地址,LoginServer將session key安全轉(zhuǎn)移給目標(biāo)服務(wù)器,轉(zhuǎn)移的意思是要確保目標(biāo)服務(wù)器收到了session key,本地保存的要刪除掉。所以,我們也可以試著考慮一種新的方案,一種不需要去全區(qū)唯一一個入口查詢的方案。那么,LoginServer將這個key存到數(shù)據(jù)庫中,讓網(wǎng)關(guān)服自己去數(shù)據(jù)庫驗(yàn)證?似乎也是個可行的方案。一樣的處理過程,我們的登錄服在驗(yàn)明客戶端身份后,也會發(fā)給客戶端一個登機(jī)牌,這個登機(jī)牌還有一個學(xué)名,叫做session key。這是一個很必要的設(shè)計(jì),保證了我們在因意外情況連接不上世界服或者發(fā)現(xiàn)世界服正在排隊(duì)而想換另外一個試試時不會需要重新進(jìn)行密碼驗(yàn)證。如果客戶端一直連接著,則該狀態(tài)會以每5秒一次的頻率不停刷新列表給客戶端,當(dāng)然是否值得這樣做還是有待商榷。密碼驗(yàn)證的過程使用了SRP6協(xié)議,具體過程就不多做描述,每個游戲使用的方式也都不大一樣。WorldServerMgr實(shí)現(xiàn)所要考慮的內(nèi)容就這些,我們再來看看LoginServer,這才是我們今天要重點(diǎn)討論的對象。這里可以用一個心跳包來實(shí)現(xiàn)其狀態(tài)的檢測,如果WorldServer的連接斷開或者在規(guī)定時間內(nèi)未收到心跳包,則將其狀態(tài)更新為離線。從上面的過程描述中,我們很容易想到利用一個臨時的列表來保存世界服信息,這也是我們增加WorldServerMgr服務(wù)器的目的所在。在mangos的代碼中,我們注意到登錄服是從數(shù)據(jù)庫中取的世界列表,而在wow官方服務(wù)器中,我們卻會注意到,這個世界服列表并不是一開始就固定,而是動態(tài)生成的。GateWay/WorldServer GateWay/WodlServer LoginServer LoginServer DNSServer WorldServerMgr | | | | | | | | internet | clients其中DNSServer負(fù)責(zé)帶負(fù)載均衡的域名解析服務(wù),返回LoginServer的IP地址給客戶端。在上面的文字中就同時出現(xiàn)了消息、事件和信號三個相近的概念,而在實(shí)際處理中,經(jīng)常發(fā)現(xiàn)三者不知道如何界定的情況,實(shí)際的情況比我在這里描述的要混亂的多。而信號的處理方式有些不同,信號處理是立即回調(diào)的,也就是一個信號產(chǎn)生后,他上面所注冊的所有槽都會立即被回調(diào)。對于信號的處理則比較簡單,默認(rèn)是沒有順序的,如果需要明確的順序,可以在信號注冊時顯示地指明槽的位置。關(guān)于事件和信號機(jī)制的實(shí)現(xiàn),網(wǎng)絡(luò)上的開源訓(xùn)也比較多,比如FastDelegate,sigslot,boost::signal等,其中sigslot還被Google采用,在libjingle的代碼中我們可以看到他是如何被使用的。但有一項(xiàng)區(qū)別在于,事件處理函數(shù)的返回值是有意義的,我們要根據(jù)這個返回值來確定是否還要繼續(xù)事件的處理,比如在QT中,事件處理函數(shù)如果返回true,則這個事件處理已完成,QApplication會接著處理下一個事件,而如果返回false,那么事件分派函數(shù)會繼續(xù)向上尋找下一個可以處理該事件的注冊方法。比如在QT應(yīng)用程序中,用戶的一次鼠標(biāo)點(diǎn)擊會產(chǎn)生一個鼠標(biāo)點(diǎn)擊事件加入到事件隊(duì)列中,當(dāng)處理此事件時可能會導(dǎo)致某個按鈕控件產(chǎn)生一個clicked()信號。比如在游戲服務(wù)器上玩家的狀態(tài)管理,還有在實(shí)現(xiàn)NPC人工智能時的各種狀態(tài)管理,這些就留作以后的專題吧。當(dāng)我們在進(jìn)行狀態(tài)轉(zhuǎn)換時,可能會需要將一些現(xiàn)場數(shù)據(jù)從老狀態(tài)對象轉(zhuǎn)移到新狀態(tài)對象,這需要在定義接口時做一下考慮。當(dāng)要進(jìn)行狀態(tài)轉(zhuǎn)換時,調(diào)用MachineBase的ChangeState()方法,顯示地告訴狀態(tài)機(jī)管理類自己要轉(zhuǎn)到哪一個狀態(tài)。狀態(tài)機(jī)基類接口:MachineBase{void ChangeState(StateBase* state)= 0。稍作整理,大概的代碼會類似這樣:狀態(tài)基類接口:StateBase{void Enter()= 0。描述的情況與我們這里所要處理的情況是如此的相似,也許我們可以試一試。該結(jié)構(gòu)體定義了每個消息碼的處理函數(shù)及需要的狀態(tài)標(biāo)識,只有當(dāng)前狀態(tài)滿足要求時才會調(diào)用指定的處理函數(shù),否則這個消息碼的出現(xiàn)是不合法的。首先還是從mangos的代碼開始看起,我們注意到登錄服在處理客戶端發(fā)來的消息時用到了這樣一個結(jié)構(gòu)體:struct AuthHandler{eAuthCmd cmd。采用第二種方式還可以附帶一個優(yōu)化方案。但是直接send調(diào)用有時候有會存在一些問題,比如遇到系統(tǒng)的發(fā)送緩沖區(qū)滿而阻塞住的情況,或者只發(fā)送了一部分?jǐn)?shù)據(jù)的情況也時有發(fā)生。因?yàn)槲覀儗ν粋€隊(duì)列不再會出現(xiàn)同時讀和寫的情況,每個隊(duì)列在寫滿后交給邏輯線程去讀,邏輯線程讀完后清空隊(duì)列再交給IO線程去寫,一段固定大小的緩沖區(qū)即可。環(huán)形緩沖區(qū)是一項(xiàng)很好的技術(shù),不用頻繁的分配內(nèi)存,而且在大多數(shù)情況下,內(nèi)存的反復(fù)使用也使得我們能用更少的內(nèi)存塊做更多的事。要是一直這么反著追,估計(jì)您就只能換一個跑的更快的追逐者了,要不這游戲還真沒法玩下去。但是對于這種按照嚴(yán)格的先進(jìn)先出順序處理的,塊大小并不算小的,而且塊大小也并不統(tǒng)一的內(nèi)存分配情況來說,更多使用的是一種叫做環(huán)形緩沖區(qū)的方案,mangos的網(wǎng)絡(luò)代碼中也有這么一個東西,其原理也是比較簡單的。arthur的方案很好的解決了上一個方案遺留的問題,但因?yàn)橹挥幸粋€寫隊(duì)列,所以當(dāng)想要提供多個IO線程時,線程間互斥地寫入數(shù)據(jù)可能會增大競爭的機(jī)會,當(dāng)然,如果只有一個IO線程那將是非常完美的。雖然看起來鎖的調(diào)用次數(shù)是比前一種方案要多很多,但實(shí)際上大部分鎖調(diào)用都是不會引起阻塞的,只有在邏輯線程調(diào)換隊(duì)列的那一瞬間可能會使得某個線程阻塞一下。Ghost Cheng在他的描述中沒有講到如何解決這種問題,但我們可以先來看看另一個方案。而邏輯線程取消息時是從隊(duì)列容器中取一個有消息的隊(duì)列來讀取,處理完后清空隊(duì)列再放回到容器中。其最大的問題在頻繁的鎖競爭上。有關(guān)消息隊(duì)列的實(shí)現(xiàn)和線程間消息的傳遞在ACE中有比較完全的代碼實(shí)現(xiàn)及描述,還有一些使用示例,是個很好的參考。好比是,我這里提供了一個倉庫,有很多的供貨商,他們有貨要給我的時候只需要交到倉庫,然后我再到倉庫去取就是了,這個倉庫也就是消息隊(duì)列。我們可以用一段簡單的偽碼來描述這個循環(huán)過程:while(Message* msg = getMessage()){if(msg為服務(wù)器關(guān)閉消息)break。另外對于大多數(shù)服務(wù)器程序來說,在運(yùn)行時都是作為精靈進(jìn)程或服務(wù)進(jìn)程的,所以我們并不需要服務(wù)器能夠
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評公示相關(guān)推薦
文庫吧 www.dybbs8.com
備案圖鄂ICP備17016276號-1