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.
363 lines
10 KiB
363 lines
10 KiB
using System;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
|
|
using Sog;
|
|
using Sog.Log;
|
|
using Sog.IO;
|
|
|
|
namespace SMAgent
|
|
{
|
|
public class SMAgentApp
|
|
{
|
|
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 SMAgentApp(AppParam appParam)
|
|
{
|
|
m_appParam = appParam;
|
|
|
|
m_app = new ServerApp(m_appParam);
|
|
|
|
m_serverType = (ServerType)ServerIDUtils.GetServerType(m_app.ServerID);
|
|
|
|
//初始化日志等级,文件路径,文件名
|
|
TraceLog.SetLogPathName("../log/", "smagent");
|
|
SetLogReloadableParam();
|
|
|
|
m_app.OnTick += this.OnTick;
|
|
}
|
|
|
|
private void SetLogReloadableParam()
|
|
{
|
|
TraceLog.SetLogLevel(LogLevel.Trace);
|
|
}
|
|
|
|
//初始化,读取cluster的配置文件,这个将会建立管道配置
|
|
private int Init()
|
|
{
|
|
int iRet = InitShmCommand();
|
|
if(iRet != 0)
|
|
{
|
|
return iRet;
|
|
}
|
|
|
|
//初始化时区相关信息
|
|
AppTime.InitTimeZone();
|
|
|
|
GCMonitor.Instance.CloseLog(1);
|
|
|
|
SMAgentUtils.Config = JsonConfig.parseFile<SMAgentConfig>("../cfg/SMAgent.json");
|
|
|
|
SMAgentUtils.Init(m_app);
|
|
|
|
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;
|
|
|
|
SMAgentNet.Instance.Start();
|
|
}
|
|
|
|
TryReadShmCommand(tMs);
|
|
|
|
//优先执行命令
|
|
if (string.IsNullOrEmpty(m_serverCommand) == false)
|
|
{
|
|
string strcommand = m_serverCommand;
|
|
m_serverCommand = null;
|
|
ProcessShmCommand(strcommand);
|
|
}
|
|
|
|
AgentFileTransMng.Instance.Tick(tMs);
|
|
AgentFileRecvMng.Instance.Tick(tMs);
|
|
|
|
|
|
SMAgentNet.Instance.Update(tMs);
|
|
|
|
SMPingSvc.Update(tMs);
|
|
|
|
SMAgentCommand.Instance.Update(tMs);
|
|
|
|
SMShell.UpdateProcessExit(tMs);
|
|
|
|
//统计下Tick的效率,看1秒能够Tick多少次
|
|
ServerStat.Instance.AddValue("TickCount", 1);
|
|
|
|
ServerStat.Instance.Tick(tMs);
|
|
}
|
|
|
|
//启动服务器
|
|
public void Start()
|
|
{
|
|
int bRet = Init();
|
|
if(bRet == 0)
|
|
{
|
|
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");
|
|
|
|
SMShell.CancelShell();
|
|
SMAgentCommand.Instance.Stop();
|
|
m_app.StopServer();
|
|
m_app.SetStopSuccess();
|
|
|
|
return;
|
|
}
|
|
|
|
private void ProcessShmCommand_ReloadConfig()
|
|
{
|
|
TraceLog.Debug("ProcessShmCommand_ReloadConfig");
|
|
}
|
|
|
|
private void ProcessShmCommand_GmCommand(string[] splitStr)
|
|
{
|
|
//TraceLog.Debug("ProcessShmCommand_GmCommand");
|
|
|
|
GmCommandMgr.Instance.HandlerGmCommandBySplit(splitStr);
|
|
}
|
|
}
|
|
}
|
|
|