using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using Sog.Service; using ProtoCSStruct; namespace GameDB { //每个Task需要一个Handler,一个Handler一个DBOperator public class MessageTaskHandler { /// /// 不要修改这个数量,除非你真的搞明白了db的多工作线程和db多进程的关系!! /// public const int GameDBWorkThreadCount = 10; private GameDBOperator m_dbOperator; private GameDBOperator m_oldDBOperator; private long m_lastKeepMysqlConnTimeSecond; //自管理 private static MessageTaskHandler[] m_allTaskHandler; public static void InitAllTaskHandler(ServerApp app) { //分配消息任务,线程数量 uint iTaskCount = (uint) GameDBWorkThreadCount; TraceLog.Debug("MessageTaskHandler.InitAllTaskHandler messageTaskCount is {0}", iTaskCount); MessageTaskDistributor.Instance.InitTask(iTaskCount, app); GameDBServerConfig serverConfig = GameDBServerUtils.GetServerConfig(); GameDBServerUtils.ParseDBConfig(app, out int dbtype, out string dbname, out string dbip); m_allTaskHandler = new MessageTaskHandler[iTaskCount]; for (int i = 0; i < m_allTaskHandler.Length; i++) { m_allTaskHandler[i] = new MessageTaskHandler(); switch (dbtype) { case 0: m_allTaskHandler[i].m_dbOperator = new MysqlGameDBOperator(dbname, dbip , serverConfig.dbuser, serverConfig.dbpassword); break; case 2: m_allTaskHandler[i].m_dbOperator = new RedisGameDBOperator(dbname, dbip , serverConfig.dbuser, serverConfig.dbpassword); break; default: TraceLog.Error("MessageTaskHandler.InitAllTaskHandler invalid dbtype {0}", dbtype); break; } MessageTaskObj taskObj = MessageTaskDistributor.Instance.GetTaskByIndex(i); taskObj.Handler = m_allTaskHandler[i].HandlerPacket; taskObj.IdleTick = m_allTaskHandler[i].OnIdleTick; } MessageTaskDistributor.Instance.StartAllTask(); } public static void DisposeAllHandler() { //关闭所有消息处理任务 MessageTaskDistributor.Instance.CloseAllTask(); if (m_allTaskHandler == null) { return; } //销毁数据库连接,销毁对象 for (int i = 0; i < m_allTaskHandler.Length; i++) { m_allTaskHandler[i].m_dbOperator.Dispose(); m_allTaskHandler[i].m_dbOperator = null; } m_allTaskHandler = null; } public static void AfterReloadServerConfigChangeDB(ServerApp app) { GameDBServerConfig serverConfig = GameDBServerUtils.GetServerConfig(); GameDBServerUtils.ParseDBConfig(app, out int dbtype, out string dbname, out string dbip); for (int i = 0; i < m_allTaskHandler.Length; i++) { m_allTaskHandler[i].m_oldDBOperator = m_allTaskHandler[i].m_dbOperator; m_allTaskHandler[i].m_lastKeepMysqlConnTimeSecond = AppTime.GetNowSysSecond(); switch (dbtype) { case 0: m_allTaskHandler[i].m_dbOperator = new MysqlGameDBOperator(dbname, dbip , serverConfig.dbuser, serverConfig.dbpassword); break; case 2: m_allTaskHandler[i].m_dbOperator = new RedisGameDBOperator(dbname, dbip , serverConfig.dbuser, serverConfig.dbpassword); break; default: TraceLog.Error("MessageTaskHandler.AfterReloadServerConfigChangeDB invalid dbtype {0}", dbtype); break; } } } public void OnIdleTick(long idleSecond) { //5分钟保持连接一次 if (AppTime.GetNowSysSecond() - m_lastKeepMysqlConnTimeSecond < 300) { return; } if (m_oldDBOperator != null) { m_oldDBOperator.Dispose(); m_oldDBOperator = null; } m_lastKeepMysqlConnTimeSecond = AppTime.GetNowSysSecond(); m_dbOperator.KeepAlive(); } public void HandlerPacket(uint remoteAppID, StructPacket packet) { //去掉这里的时间重置逻辑,如果下面实际处理逻辑里没有进行sql查询就返回会造成KeepAlive不执行 //m_lastKeepMysqlConnTimeSecond = AppTime.GetNowSysSecond(); switch (packet.MsgID) { case (int) SSGameMsgID.QueryRoleDbReq: RoleOp.OnQueryRoleReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.SaveRoleReq: RoleOp.OnSaveRoleReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.FirebaseidSaveDbReq: RoleOp.OnFirebaseidSaveDbReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.FirebaseidQueryDbReq: RoleOp.OnFirebaseidQueryDbReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.GmSetFreezeTime: RoleOp.OnSetFreezeTime(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.EnableSendMsgReq: RoleOp.OnHandleEnableMsg(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.GmQueryUserRoleReq: RoleOp.OnGMQueryRoleReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.OperationCostItemReq: RoleOp.OnCostBagItem(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.OperationUpdateTaskReq: RoleOp.OnDoneTask(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.GmUpdateUserRoleReq: RoleOp.OnGmUpdateRoleData(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.GmImportUserRoleReq: RoleOp.OnGmImportRoleData(remoteAppID, packet, m_dbOperator); break; //rank case (int) SSGameMsgID.QueryRankDbReq: RankOp.OnQueryRankReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.SaveRankDbReq: RankOp.OnSaveRankReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.QueryActRankDbReq: RankOp.OnQueryActRankDbReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.SaveActRankDataReq: RankOp.OnSaveActRankDataReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.PlayerQueryOfflineRoleReq: RoleOp.OnPlayerQueryOfflineRoleReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.PlayerSearchRoledbBynameReq: RoleOp.OnPlayerSearchRoledbBynameReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.QueryBattleReplayDbReq: MainlandRecordOp.OnQueryBattleReplayDbReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.SaveBattleReplayDbReq: MainlandRecordOp.OnSaveBattleReplayDbReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.DeleteBattleReplayDbReq: MainlandRecordOp.OnDeleteBattleReplayDbReq(remoteAppID, packet, m_dbOperator); break; //friend case (int) SSGameMsgID.QueryFriendListReq: FriendDBOp.OnQueryFriendListReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.QueryFriendInfoCacheReq: FriendDBOp.OnQueryFriendInfoCacheReq(remoteAppID, packet, m_dbOperator); break; case (int) SSGameMsgID.SaveFriendListReq: FriendDBOp.OnSaveFriendListReq(remoteAppID, packet, m_dbOperator); break; //全局数据 case (int) SSGameMsgID.WorldglobaldataDbOpReq: WorldglobaldataDbOp.OnWorldglobaldataDbOpReq(remoteAppID, packet, m_dbOperator); break; default: TraceLog.Error("GameDBMsgHandler unknow MsgID {0}", packet.MsgID); break; } } } }