控制檯Socket會每隔一段時間向控制檯發送保活包。如果沒有發送 那麼控制檯肯定是知道rungate沒反應了或者被關閉了 然後可以立馬又開啓。純粹是爲了私服假者簡單而考 慮。
實際只有2個Socket對象纔是最主要的。M2Sokcet和ClientSocket。
整個結構當然是使用的典型生產者消費者模型。 但是代碼結構很不清晰.而且消息的處理是使用Timer來處理,而不是線程。
程序在通過一個常量定義了在棧上的會話數量。當程序開始運行會 在棧上有一個數組 保存會話信息。 會話信息是一個結構體,內部記錄了會話的信息,比如連接時間,封包大小
以及 上次移動時間 上次通訊時間等等。
當有客戶端連接時候。會在預分頻的數組內找到一個未使用的空間。初始化這個數組的內容 將當前的客戶端連接保持在這個會話之內。
當收到客戶端的信息時候,會進行一系列合法的驗證 或者保護。最終將消息生成一個消息體:
ReviceMsgList.Add(UserData); //加入收到的消息列表內。
收收到服務端的消息的時候。將消息頭部 轉換成如下消息格式:
TMsgHeader = packed record
dwCode: LongWord;
nSocket: Integer;
wGSocketIdx: Word;
wIdent: Word;
wUserListIndex: Integer;
nLength: Integer;
end;
記錄了消息的類型 長度 和Socket句柄等消息。根據wIdent的值
case pMsg.wIdent of
GM_CHECKSERVER: begin //客戶端需要先驗證網關
boCheckServerFail := False;
dwCheckServerTimeMin := GetTickCount - dwCheckServerTick;
if dwCheckServerTimeMin > dwCheckServerTimeMax then
dwCheckServerTimeMax := dwCheckServerTimeMin;
//dwCheckServerTick := GetTickCount();
end;
GM_SERVERUSERINDEX: begin //wGSocketIdx 爲服務端的Socket句柄 這句主要是修改wUserListIndex。暫時沒看出要幹嘛
if (pMsg.wGSocketIdx < RUNATEMAXSESSION) and (pMsg.nSocket =
SessionArray[pMsg.wGSocketIdx].nSckHandle) then begin
SessionArray[pMsg.wGSocketIdx].nUserListIndex := pMsg.wUserListIndex;
end;
end;
GM_RECEIVE_OK: begin
{dwCheckServerTimeMin := GetTickCount - dwCheckRecviceTick;
if dwCheckServerTimeMin > dwCheckServerTimeMax then dwCheckServerTimeMax := dwCheckServerTimeMin;
dwCheckRecviceTick := GetTickCount(); }
SendServerMsg(GM_RECEIVE_OK, 0, 0, 0, 0, nil); //消息到達處理,貌似很沒必要吧。應該是M2會做一些處理
end;
GM_DATA: begin
ProcessMakeSocketStr(pMsg.nSocket, pMsg.wGSocketIdx, MsgBuff, pMsg.nLength);//進行編碼處理後 加入到每個會話的列表(實際是string)。此時並不是發送,並將消息加入SendMsgList;
end;
GM_TEST: begin
end;
首先此函數會更新界面顯示,(這個耦合性也太大了吧。業務邏輯 跟界面扯上了關係)。
然後將ReviceMsgList內所有的收到的消息發送給M2處理。(客戶端發送過來的)
接着將SendMsgList 內所有的消息 投遞到客戶端(每個消息包括了客戶端描述 所以可以知道應該投給哪個客戶端)。
然後每2秒向M2發送一個保活包。
總結: 網關收到客戶端的包 是直接轉發給M2的其中並沒有解密。而M2發送給客戶端的消息是要經過網關再EncodeMessage。也就是說網關並沒有承擔起完整的加解密。
M2還要負責客戶端的解密操作。可以看出傳奇的源碼在設計上不太理想。
思考: Srv處理應該主要集中在遊戲數據的處理上 而封包的加密解密 應該給遊戲網關進行。同時遊戲網關內,不宜開多線程進行操作。因爲遊戲網關面對的資源是整個計算機的 資源。過多的線程可以讓單個網關獲得比較好的效率。但是遊戲網關在設計中並不是讓自身獲得更好的效率 而是讓整個計算機的資源充分的利用。如果自身一個網關無 法處理用戶請求的時候,應該開啓多個網關協同處理。 所以在網關的設計上應該將發送和接受 編碼解碼 放在同一個線程內。以多進程取代多線程,以避免在多線程處理 因爲生產者消費者模型 而導致兩個線程實際只有一個線程在工作。 個人愚見 錯誤請指正。