You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

364 lines
9.9 KiB

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<SMCenterConfig>("../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);
}
}
}