Kevin Lynx 6.22.2010
MMORPG中,玩家的移動(dòng)主要邏輯都放在客戶端進(jìn)行,包括自動(dòng)尋路和響應(yīng)玩家的操作,服務(wù)
器在這里擔(dān)當(dāng)一個(gè)被動(dòng)角色。但是服務(wù)器端的玩家數(shù)據(jù)卻是真正的被其他邏輯模塊參考的數(shù)
據(jù)。
在這樣一種C/S主從關(guān)系中,如何保證C/S兩者各自維護(hù)的玩家坐標(biāo)數(shù)據(jù)的一致性?為了保證
數(shù)據(jù)的一致性,我們需要進(jìn)行數(shù)據(jù)的同步。而導(dǎo)致數(shù)據(jù)不同步(不相同),也就是C/S之間
玩家的坐標(biāo)不一樣,主要來源于兩大原因:C->S數(shù)據(jù)的網(wǎng)絡(luò)延遲、S->C數(shù)據(jù)的網(wǎng)絡(luò)延遲。考
慮到這兩個(gè)重要的因素,首先需要盡量減少C/S之間數(shù)據(jù)的交互。
在一般的邏輯模塊中,客戶端發(fā)送一個(gè)請(qǐng)求到服務(wù)器,服務(wù)器作了驗(yàn)證后返回驗(yàn)證結(jié)果,客
戶端接收驗(yàn)證結(jié)果繼續(xù)之前的邏輯。這對(duì)于MMO中諸如物品操作而言是足夠的,但無法應(yīng)用
于玩家移動(dòng)。
這里的做法是:客戶端每走一步,都發(fā)消息(網(wǎng)絡(luò)封包)給服務(wù)器,服務(wù)器做驗(yàn)證;客戶端
停止走動(dòng)后,通知服務(wù)器,服務(wù)器返回自己保存的坐標(biāo),客戶端在這個(gè)時(shí)候才使用服務(wù)器端
的數(shù)據(jù)同步一次本地坐標(biāo)。其操作序列如下圖:
-----------------------------------------------------------------
Client Server
移動(dòng)、本地坐標(biāo)改變 ----> 驗(yàn)證C/S之間的坐標(biāo)是否差距過大,
驗(yàn)證失敗通知客戶端停止移動(dòng)
停止移動(dòng) ----> 驗(yàn)證同上
同步本地坐標(biāo)為服務(wù)器坐標(biāo) <---
-----------------------------------------------------------------
此外,客戶端保存一個(gè)請(qǐng)求計(jì)數(shù),每一次發(fā)送一個(gè)移動(dòng)請(qǐng)求時(shí),遞增該計(jì)數(shù);服務(wù)器收到該
請(qǐng)求后,驗(yàn)證成功,返回一個(gè)消息,客戶端收到此回應(yīng)消息后遞減該計(jì)數(shù)。當(dāng)該計(jì)數(shù)超過某
個(gè)配置數(shù)值后,客戶端將忽略玩家的移動(dòng)操作。客戶端還可以將玩家的多個(gè)移動(dòng)操作合并為
一個(gè),即,只在角色到達(dá)玩家最后一次點(diǎn)擊的坐標(biāo)時(shí),才發(fā)送停止移動(dòng)消息給服務(wù)器。
配合請(qǐng)求計(jì)數(shù)機(jī)制,當(dāng)C->S的消息出現(xiàn)延遲太久時(shí),此時(shí)也意味著請(qǐng)求計(jì)數(shù)過大,客戶端會(huì)
強(qiáng)迫玩家等待;服務(wù)器終于收到消息后,逐個(gè)處理,直到處理完后,客戶端的請(qǐng)求計(jì)數(shù)恢復(fù)
時(shí),玩家才可繼續(xù)移動(dòng)。同樣,當(dāng)S->C的消息(只考慮停止移動(dòng)的消息回應(yīng))出現(xiàn)延遲時(shí),
這個(gè)時(shí)候客戶端很可能在本地做了另一次移動(dòng)操作,在終于接收到上一次移動(dòng)操作的服務(wù)器
端回應(yīng)時(shí),因?yàn)檫@個(gè)時(shí)候客戶端毫無條件地將本地?cái)?shù)據(jù)同步為服務(wù)器端發(fā)過來的數(shù)據(jù),那么
,出現(xiàn)這種情況后,客戶端角色就會(huì)出現(xiàn)拉回去的現(xiàn)象。這里的一次移動(dòng),可能是多個(gè)地圖
格子的移動(dòng),一般為角色當(dāng)前坐標(biāo)到玩家點(diǎn)擊的目標(biāo)坐標(biāo)。