using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Sog; using Sog.Service; using ProtoCSStruct; namespace Operation { //每个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 = OperationServerUtils.GetServerConfig(); m_allTaskHandler = new MessageTaskHandler[iTaskCount]; OperationServerUtils.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) { 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) { var serverConfig = OperationServerUtils.GetServerConfig(); OperationServerUtils.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) { //去掉这里的时间重置逻辑,如果下面实际处理逻辑里没有进行sql查询就返回会造成KeepAlive不执行 //m_lastKeepMysqlConnTimeSecond = AppTime.GetNowSysSecond(); TraceLog.Debug("MessageTaskHandler.HandlerPacket Handle MsgID {0}", packet.MsgID); switch (packet.MsgID) { case (int)SSGameMsgID.GetMailWithRuleReq: MailOp.OnGetMailWithRuleReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.SendMailWithRuleRes: //MailOp.OnSendMailWithRuleRes(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.PlaydataOpReq: PlaydataOp.OnGetPlayDataOpReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.EnableSendMsgRes: BanUser.OnBanChatRes(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.GmSetFreezeTimeRes: BanUser.OnBanUserRes(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.NoticeBackgroundsReq: SysNoticeBackgroungs.OnNoticeBackGroundsReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.HttpApiDbReq: HttpApiRootHandler.OnHttpApiDbReq(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.OperationFakepayRes: GMPayment.OnSendPaymentRes(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.OperationUpdateTaskRes: PlayerMonitor.OnDoneTaskRes(remoteAppID, packet, m_dbOperator); break; case (int)SSGameMsgID.SyncPresetReq: PlayerPresetOp.OnGetPresetWithRuleReq(remoteAppID, packet, m_dbOperator); break; default: TraceLog.Error("MessageTaskHandler.HandlerPacket unknow MsgID {0}", packet.MsgID); break; } } } }