using System; using System.Linq; using System.Text; using System.Threading; using Sog; using Sog.Log; using Sog.IO; namespace SMCenter { /* */ public class SMCenterApp { private ServerApp m_app; private ServerType m_serverType; private AppParam m_appParam; private IShareCommand m_shareCommand; private long m_lastReadShmCommandTime = 0; private long m_serverStartTime = 0; private System.Threading.Mutex m_procMutex; private string m_serverCommand; private bool m_serverInitedOnTick = false; public SMCenterApp(AppParam appParam) { m_appParam = appParam; m_app = new ServerApp(m_appParam); m_serverType = (ServerType)ServerIDUtils.GetServerType(m_app.ServerID); //初始化日志等级,文件路径,文件名 TraceLog.SetLogPathName("../log/", "smcenter"); SetLogReloadableParam(); m_app.OnTick += this.OnTick; } private void SetLogReloadableParam() { TraceLog.SetLogLevel(LogLevel.Trace); } //初始化, private int Init() { int iRet = InitShmCommand(); if(iRet != 0) { return iRet; } //初始化时区相关信息 AppTime.InitTimeZone(); GCMonitor.Instance.CloseLog(1); m_serverStartTime = AppTime.GetNowSysMs(); return 0; } private string GetMutexName() { return "sog_" + ServerIDUtils.IDToString(m_app.ServerID); } private bool CheckAppIsAlreadyRunning() { string mutexname = GetMutexName(); try { System.Threading.Mutex mutex; bool bRet = System.Threading.Mutex.TryOpenExisting(mutexname, out mutex); if (bRet) { return true; } } catch (Exception ex) { Console.WriteLine(ex.ToString()); return false; } return false; } private void CreateMutex() { string mutexname = GetMutexName(); m_procMutex = new System.Threading.Mutex(true, mutexname); } private int InitShmCommand() { if(m_appParam.RunMode == AppRunMode.None) { Console.WriteLine("server id {0} runmode init error", ServerIDUtils.IDToString(m_appParam.ServerID)); return 2; } //启动模式 if (m_appParam.RunMode == AppRunMode.Start) { if (CheckAppIsAlreadyRunning() == true) { string strError = string.Format("server id {0} already running,runmode Start,please check!" , ServerIDUtils.IDToString(m_appParam.ServerID)); Console.WriteLine(strError); return 1; } CreateMutex(); TraceLog.Debug("=========================================================="); TraceLog.Debug("server id {0} starting at {1}", ServerIDUtils.IDToString(m_appParam.ServerID),DateTime.Now); TraceLog.Debug("InitShmCommand server run in run mode,CreateShareCommand"); m_shareCommand = new ShareMemoryCommand(m_appParam.ServerID); m_shareCommand.Create(); return 0; } //代理启动模式 else if(m_appParam.RunMode == AppRunMode.Run) { Console.WriteLine("server id {0} runmode Run not support", ServerIDUtils.IDToString(m_appParam.ServerID)); return 9998; } //其他代理模式就是各种命令模式,写入命令后退出 else { m_shareCommand = new ShareMemoryCommand(m_appParam.ServerID); bool attachSuccess = m_shareCommand.Attach(); if (attachSuccess == false) { string strError = string.Format("server id {0} not running,please start server use start param first!" , ServerIDUtils.IDToString(m_appParam.ServerID)); Console.WriteLine(strError); return 1; } if (m_appParam.RunMode == AppRunMode.Stop) { m_shareCommand.WriteCommand("stop"); return 2; } //ReloadConfig可以带参数 if (m_appParam.RunMode == AppRunMode.ReloadConfig) { m_shareCommand.WriteCommand(m_appParam.CommandAllText); return 4; } return 9999; } //return 0; } private void TryReadShmCommand(long tMs) { if(m_lastReadShmCommandTime == 0) { m_lastReadShmCommandTime = tMs; return; } //500毫秒读一次,不存在性能问题 if(tMs - m_lastReadShmCommandTime >= 500) { m_lastReadShmCommandTime = tMs; string strCommand = m_shareCommand.ReadCommand(); if (strCommand == null) { return; } TraceLog.Debug("server read command from shm, command: {0}", strCommand); //设置这个供工作线程读取 m_serverCommand = strCommand; } } private void OnTick(long tMs) { //初始化 if(m_serverInitedOnTick == false) { m_serverInitedOnTick = true; SMCenterNet.Instance.Start(m_app); } TryReadShmCommand(tMs); //优先执行命令 if (string.IsNullOrEmpty(m_serverCommand) == false) { string strcommand = m_serverCommand; m_serverCommand = null; ProcessShmCommand(strcommand); } CenterFileTransMng.Instance.Tick(tMs); CenterFilePullMng.Instance.Tick(tMs); SMCenterNet.Instance.Update(tMs); ConsoleCmd.Instance.Update(tMs); //统计下Tick的效率,看1秒能够Tick多少次 ServerStat.Instance.AddValue("TickCount", 1); } //启动服务器 public void Start() { int bRet = Init(); if(bRet == 0) { SMCenterUtils.Config = JsonConfig.parseFile("../cfg/SMCenter.json"); SMCenterUtils.Init(m_app); SMProcAppMgr.Instance.ReadClusterConfig(); CmdProcFactory.Init(); m_app.Run(); //正常进程退出sleep一下,确保log写完 Thread.Sleep(500); //游戏服务器退出的时候需要调用,资源释放使用 if (m_shareCommand != null) { m_shareCommand.DeleteFile(); m_shareCommand.Close(); m_shareCommand = null; } if (m_procMutex != null) { m_procMutex.Dispose(); m_procMutex = null; } TraceLog.Debug("server id {0} stoped at {1}", ServerIDUtils.IDToString(m_appParam.ServerID), DateTime.Now); } else { //代理服务器退出的时候需要调用,资源释放使用 if (m_shareCommand != null) { m_shareCommand.Close(); m_shareCommand = null; } } if (bRet != 0) { //> 0 算是正常执行完了程序,比如reload等 if(bRet > 0) { return; } string strError = string.Format("call Init failed,server end"); try { TraceLog.Error(strError); } catch(Exception ex) { ex.Source = null; } Console.WriteLine(strError); return; } } //读取指令 private void ProcessShmCommand(string strCommand) { TraceLog.Debug("ProcessShmCommand cmd:{0}", strCommand); if (strCommand == "stop") { ProcessShmCommand_Stop(); } else if(strCommand == "reload") { } else if(strCommand == "reloadconfig") { ProcessShmCommand_ReloadConfig(); } else { if(strCommand.Contains(' ')) { string[] splitStr = strCommand.Split(' '); if(splitStr.Length >= 2 && splitStr[0] == "gmcmd") { ProcessShmCommand_GmCommand(splitStr); } } } } private void ProcessShmCommand_Stop() { TraceLog.Debug("ProcessShmCommand_Stop"); m_app.StopServer(); m_app.SetStopSuccess(); return; } private void ProcessShmCommand_ReloadConfig() { TraceLog.Debug("ProcessShmCommand_ReloadConfig"); SMProcAppMgr.Instance.ReadClusterConfig(); } private void ProcessShmCommand_GmCommand(string[] splitStr) { //TraceLog.Debug("ProcessShmCommand_GmCommand"); GmCommandMgr.Instance.HandlerGmCommandBySplit(splitStr); } } }