近些天寫了一些游戲邏輯,發(fā)現(xiàn)項目組在寫C/S網(wǎng)絡(luò)消息包的時候,根據(jù)作用的不同,定義了很多的不同的消息格式。比如,所有的消息包都繼承自下面這個基本結(jié)構(gòu)。
struct?SPacket


{
??byte??bType;
}然后,添加物品的消息包,設(shè)置成員狀態(tài)的消息包都分別定義了不同的結(jié)構(gòu)。
struct?SAddItemPacket?:?public?SPacket


{
??SItem?item;
??SAddItem()

??
{
????bType?=?STC_AddItem;
??}
}

struct?SSetMemberPacket?:?public??SPacket


{
??byte??bStatus;
??SSetMemberPacket()

??
{
????bType?=?STC_SetMember;
??}
}隨著項目填充越來越多的內(nèi)容,消息包的類型越來越多,不能避免嗎?
晚上睡覺的時候,想著如果把網(wǎng)絡(luò)引擎引入項目之類的會怎樣呢?然后想到看過的ICE教程,就大概的思考類似ICE這樣的通用RPC大概是怎樣實現(xiàn)的。
RPC由服務(wù)對象以及其客戶端的表現(xiàn)——代理對象構(gòu)成。客戶端代碼中,調(diào)用了代理對象的某個接口,就會導(dǎo)致其服務(wù)對象執(zhí)行該接口的實現(xiàn),使得客戶端看起來就像是執(zhí)行本地調(diào)用一樣。
因此RPC的直觀概念是接口調(diào)用的網(wǎng)絡(luò)映射,核心內(nèi)容是:如何將客戶端調(diào)用(某個對象的)某個接口的這一行為進行通用的序列化?
對調(diào)用行為序列化和對對象序列化是不同的,而且RPC的目標(biāo)是對任何類型的接口調(diào)用行為都能有一個通用的序列化方案。
我們要調(diào)用某個接口的時候,下達的命令通常是,“某某類型的,那個誰,把你的那個名叫什么的方法調(diào)用一下,參數(shù)是這些,a,b,c,d”。這樣我們就進行了一次接口調(diào)用。因此,調(diào)用行為最基本的序列化方法是,類型ID+方法ID+對象ID+參數(shù)。將這些數(shù)據(jù)加成起來,就能作為一個調(diào)用消息包由客戶端發(fā)向服務(wù)器,服務(wù)器處理RPC管理的對象將會根據(jù)類ID,對象ID找到服務(wù)對象,然后根據(jù)方法ID,找到方法,并能根據(jù)方法知道有幾個參數(shù),以及參數(shù)的類型,最終執(zhí)行調(diào)用。
因此,我此時覺得,像項目組現(xiàn)在定義的多種大小不變,種類繁多的消息格式,其實都可以用一個能序列化調(diào)用行為的消息包來解決。該消息包的結(jié)構(gòu)是:
class??SPacket


{
??WORD??wClassID;
??WORD??wMemberFuncID;
??BYTE??bParam[PACKET_PARAM_BUFFER_SIZE];
??QWORD??qwBufferOffset?=?0;

public:
??SPacket(WORD?par_wClassID,WORD?par_FuncID,?DWORD?dwObjID);
??SPacket(WORD?par_wClassID,WORD?par_FuncID,?QWORD?qwObjID);

??template<typename?T>
??bool??Push(T?value)

??
{
????memcpy(bParam?+?qwBufferOffset,value,sizeof(T);
????qwBufferOffset?+=?sizeof(T);
??}

??bool??Pop(T?&value)

??
{
????T??*pValue?=?static_cast<T*>(bParam?+?qwBufferOffset)
????value?=?*pValue;
????qwBufferOffset?+=?sizeof(T);
??}

??QWORD??Size()?const

??
{
????return??sizeof(wClassID)?+?sizeof(wMemberFuncID)?+?qwBufferOffset;
??}
};參數(shù)從左到右裝入消息包,相應(yīng)的也是從左到右從消息包取出,來配合服務(wù)器端執(zhí)行相應(yīng)的函數(shù)。
posted on 2007-01-26 23:26
LOGOS 閱讀(2497)
評論(12) 編輯 收藏 引用