mangos源碼分析

mangos源碼分析

轉自:http://eric-weitm.iteye.com/blog/1457395

mangos 的執行模型 
一、線程分佈: 
1、主線程 main---- Master::Run() ,主要功能:初始化world、創建子線程、回收資源 
2、WorldRunnable -------GS主線程 
3、CliRunnable -----後臺調試線程 
4、RARunnable -------事件處理和分發線程 
5、MaNGOSsoapRunnable---協議 
6、FreezeDetectorRunnable 
7、線程池  Master::Run----WorldSocketMgr::StartNetwork---WorldSocketMgr::StartReactiveIO ---ReactorRunnable 

二、事件分發和處理 
WorldRunnable::run---World:update----World:UpdateSessions---WorldSession::Update(一個socket內所有事件)---各種各樣的handler 

基本框架:ACE的Reactor機制(ACE_TP_Reactor) 

三、WorldRunnable 主要功能 
WorldRunnable ----World 定時器任務+網絡事件(session中的)+異步IO回調+任務系統調度+cli

整個game server的併發模型 

一 概述 
game server至少要提供如下幾類的功能 : 
  1、響應客戶端請求-------WorldRunnable 
  2、後臺命令  -------CliRunnable 
  3、分佈式架構(RMI等) -------MaNGOSsoapRunnable 

可以看到針對這幾類功能,mangos都給予了支持。 

二、WorldRunnable響應客戶端請求的併發實現 
  game server會提供很多服務,如組隊、加好友、交易、走路、戰鬥……,從宏觀上講這些服務是同時對外提供的,另外IO操作是費時的, 
必須將IO與邏輯處理分開,這樣的話一個基本的實現是這樣的: 
1、開啓IO線程,所有費時的操作交由此處處理   WorldDatabase.ThreadStart(); 
2、利用協程來實現各個子系統,或者利用心跳來實現各個子系統的調度(不能開很多線程,線程代價太高) 

三、Mangos的心跳實現 
void World::Update(uint32 diff) 
  基本上包括幾類: 
  1、檢查定時器---------------時間 
  2、刷任務 
  3、維護session---------------------人物 
  4、全局環境更新(map、battleGround)--------地點 
  5、處理服務器事件------------------事件 
  6、其他(數據同步、後臺調試、IO回調……) 

四、game server運行的機制 
  1、定時器觸發 
  2、事件觸發(鬆耦合) 

五、典型的一種service的實現方式 
1、IO協程將cammand入隊 
2、worker協程 依次fetch、execute 
   核心數據結構是線程安全的隊列

 

GS生命期內主要的事件---------狀態機的狀態轉換主要是基於事件 

一 game server狀態機 
startup 
LOAD 
Compile 
init 
running 
shutdown 

二 角色狀態機 
login 
enter_world 
enter_map 
leave_map 
leave_world 
relogin 
logout 

三 角色commands的命令種類 
login、auction, buy, chat, express, move, task, select_menu_item, stall…… 

四 server端service的組織 
  1、結構化(純c實現) clone, feature、cmds(命令入口filter)、daemons(抽象的功能模塊) 
  2、OO  各個層次的router,XXHandler, 一般在session中的總入口是player

 

session管理


一、world核心數據結構:環境+session 
SessionMap m_sessions; 
Queue m_QueuedSessions; 
typedef UNORDERED_MAP<uint32, Weather*> WeatherMap; 
        WeatherMap m_weathers; 

二、WorldSession 核心數據結構 玩家+信道+消息隊列 
  Player *_player; 
  WorldSocket *m_Socket; 
  ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue; // 每個session有一個消息隊列 

整個session就是不停的fetch,處理msg的過程 
  OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];  // 利用一次映射找到handler 
handle_input_payload----int WorldSocket::ProcessIncoming (WorldPacket* new_pct)--------void WorldSession::QueuePacket(WorldPacket* new_packet) 

三、player核心數據結構 map、權限、社會關係、管理員?拍賣?談話 存儲 包裹 物品…… 

概述:所有command緩存在socket的隊列中,各個子系統的總入口是player 

服務端每一幀的邏輯: 
1、從OS處取出到達的事件到本進程(所有的事件已經緩存在socket隊列中) 
2、依次調度各個子系統或子子系統 

對於node.js而言,線程調度、事件緩存、回調機制已經都實現了,程序員只要實現具體的邏輯和定時器(子系統)就可以了

 

game server內嵌的http服務

如何使gs響應http的請求? 基本思路 實現簡單的http server框架、具體遊戲邏輯轉發給內部handler來處理 

一 初始化 
  開啓監聽線程(協程)檢查端口、設置緩衝區大小 
  每一個socket連過來時 1、開新協程處理(有調度開銷)  2、放入共享隊列中,由worker線程池共同維護(有數據同步的問題) 
  設置每個請求URI對應的回調接口 

二 服務期 
  1、一個socket數據到來後,開新線程,解析http數據,分析出請求的uri、回調、關閉socket、關閉線程(因爲http是無連接的) 
  2、一個socket到來時,其被放入某個thread內部的sockets數組中, 
    當此worker thread池被調度到之後,依次處理每個socket的數據就可以了(唯一區別是多個sockets由幾個線程維護)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章