当前位置: 首页 > 工具软件 > MaNGOS Game > 使用案例 >

mangos源码分析

高豪
2023-12-01
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由几个线程维护)

 


 类似资料: