using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using Sog.Service; using ProtoCSStruct; namespace PlayerOp { //每个Task需要一个Handler,一个Handler一个DBOperator public class MessageTaskHandler { //不要修改这个数量,除非你真的搞明白了db的多工作线程和db多进程的关系!! public const int DBWorkThreadCount = 10; private DBOperator m_dbOperator; private long m_lastKeepMysqlConnTimeSecond; //自管理 private static MessageTaskHandler[] m_allTaskHandler; //旧的mysql连接 private DBOperator m_oldDBOperator = null; public static void InitAllTaskHandler(ServerApp app) { //分配消息任务,线程数量 uint iTaskCount = (uint)DBWorkThreadCount; TraceLog.Debug("MessageTaskHandler.InitAllHandler messageTaskCount is {0}", iTaskCount); MessageTaskDistributor.Instance.InitTask(iTaskCount, app); var serverConfig = PlayerOpServerUtils.GetServerConfig(); m_allTaskHandler = new MessageTaskHandler[iTaskCount]; PlayerOpServerUtils.ParseDBConfig(app, out int dbtype, out string dbname, out string dbip); for (int i = 0; i < m_allTaskHandler.Length; i++) { m_allTaskHandler[i] = new MessageTaskHandler(); if (dbtype == 0) { m_allTaskHandler[i].m_dbOperator = new MySqlDBOperator(dbname, dbip, serverConfig.dbuser, serverConfig.dbpassword); } else { TraceLog.Error("MessageTaskHandler.InitAllTaskHandler invalid dbtype {0}", dbtype); } 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) { //销毁数据库连接,销毁对象 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) { var serverConfig = PlayerOpServerUtils.GetServerConfig(); PlayerOpServerUtils.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() ; //建立新的链接 if (dbtype == 0) { m_allTaskHandler[i].m_dbOperator = new MySqlDBOperator(dbname, dbip , serverConfig.dbuser, serverConfig.dbpassword); } else { TraceLog.Error("MessageTaskHandler.AfterReloadServerConfigChangeDB invalid dbtype {0}", dbtype); } } } 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) { TraceLog.Debug("MessageTaskHandler.HandlerPacket Handle MsgID {0}", packet.MsgID); switch (packet.MsgID) { case (int)SSGameMsgID.ExchangeRecordQueryDbReq: PlayerOpServerUtils.GetExchangeOp().OnExchangeRecordUpdateDbReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.ExchangeRecordSaveDbReq: PlayerOpServerUtils.GetExchangeOp().OnExchangeRecordSaveDbReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.ExchangeSaveDbReq: PlayerOpServerUtils.GetExchangeOp().OnSaveExchangeCode(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.ExchangeQueryDbReq: PlayerOpServerUtils.GetExchangeOp().OnExchangeQueryDbReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.ExchangeStatusChangeReq: PlayerOpServerUtils.GetExchangeOp().OnExchangeChangeStatus(remoteAppID, packet, m_dbOperator); break; default: TraceLog.Error("MessageTaskHandler.HandlerPacket unknow MsgID {0}", packet.MsgID); break; } } } }