/* * 由SharpDevelop创建。 * 用户: Administrator * 日期: 2018-09-13 * 时间: 17:14 * * 要改变这种模板请点击 工具|选项|代码编写|编辑标准头文件 */ using System; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using GameData; using MrWu.Debug; using MrWu.RabbitMQ; using Server.Data.Module; using Server.DB.Redis; using Server.DB.Sql; using Server.MQ; using Server.Pack; using Server.Config; using Server.Core; using Server.Net; namespace Server { /// /// 全局管理 /// public abstract partial class GlobalManager : ITimerProcessor, IServer { /// /// 是否需要重新加载配置 /// public bool IsReloadTable; /// /// 服务器单元工厂 /// public static ServerUtilFactory Factory; private static GlobalManager mInstance; /// /// 每个服务器只能管理一个服务,单例模式 /// public static GlobalManager instance { get { if (mInstance == null) mInstance = Factory.GetGlobalManager(); return mInstance; } } #region 数据 /// /// 是否自杀 /// public bool isKill { get; private set; } /// /// 是否可以开战,关闭服务器前先禁止,然后再关闭服务器 /// public bool IsCanWar = true; /// /// 客户端要得到的配置 /// public ConfigHead ClientConfig; /// /// 服务器信息 /// protected ServerInfo m_serverinfo; /// /// 服务器信息 /// public virtual ServerInfo serverinfo { get { if (m_serverinfo == null) m_serverinfo = new ServerInfo(); return m_serverinfo; } } #endregion /// /// 获取配置头 /// /// protected virtual ConfigHead GetConfigHead() { ConfigHead cfh = new ConfigHead(); cfh.style = 1; cfh.id = ServerConfigManager.Instance.NodeId; cfh.num = ServerConfigManager.Instance.NodeNum; cfh.maxSVer = ServerConfigManager.Instance.MaxVer; cfh.minSVer = ServerConfigManager.Instance.MinVer; cfh.maxCver = ServerConfigManager.Instance.MaxCVer; cfh.minCver = ServerConfigManager.Instance.MinCVer; return cfh; } /// /// 设置系统时间间隔 /// /// [DllImport("winmm")] protected static extern void timeBeginPeriod(int t); /// /// 恢复系统时间间隔 /// /// [DllImport("winmm")] protected static extern void timeEndPeriod(int t); /// /// 定时器管理 /// private TimerManager timermgr; /// /// 更新服务器信息的时间 /// public int updateServerInfo_time; /// /// 更新服务器信息 /// protected virtual void UpdateServerInfo(bool isStart = false) { timeBeginPeriod(1); serverinfo.moduleId = myUtil.id; serverinfo.nodenum = myUtil.nodeNum; if (isStart) serverinfo.startTime = DateTime.Now; serverinfo.serverName = ServerName; serverinfo.dopackCnt = 0; serverinfo.minfps = minfps; serverinfo.fps = Fps; serverinfo.maxRuntime = maxruntiming; serverinfo.ConnectCnt = UserSessionsInfo.GetAllSessionCount(); serverinfo.BindConnectCnt = UserSessionsInfo.GetBindSessionCount(); updateServerInfo_time = ServerConfigManager.Instance.UpdateServerInfoTime; } /// /// 更新 /// protected virtual void Update() { TimeInfo.Instance.Update(); // long key = Debug.StartTiming(); GameNetDispatcher.Instance.Update(); GlobalDispatcher.Instance.Update(); GameDispatcher.Instance.Update(); // double runtime = Debug.GetRunTime(key); // if (runtime > 200) // { // Debug.Error($"Update: 处理慢:{runtime}"); // } } /// /// 启动数据 /// /// protected virtual bool Init() { return true; } private void DayChange() { GameDispatcher.Instance.Dispatch(GameMsgId.DayChange); } /// /// fps计数 /// private int fpscount = -1; /// /// 帧率 /// public int Fps { get; protected set; } private int m_minfps = -1; /// /// 最小fps /// public int minfps { get { return m_minfps; } protected set { m_minfps = value; } } /// /// 最大运行时间 /// public double maxruntiming { get; protected set; } private System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); /// /// 发送配置包裹 /// protected virtual void SendConfigPack() { } /// /// 处理模块死亡信号 /// /// /// protected void DoModuleDieSign(object param) { if (param is ServerNode serverNode) { Debug.Info("模块死亡包处理!"); PackHead head = PackHead.Create(); head.packlx = ServerPackAgreement.ModuleDie; Message msg = GlobalMQ.CreateMessage(head, serverNode); GlobalMQ.instance.AddMessage(msg); head.Dispose(); } } /// /// 发送开启节点包 /// protected virtual void SendOpenNode() { //注册模块 PackHead head = PackHead.Create(); head.packlx = ServerPackAgreement.openNode; var data = this.myType != ModuleType.WatchDog ? MonitoringAppInfo : null; GlobalMQ.instance.DeliveryAll(GlobalMQ.CreateMessage(head, data), true); head.Dispose(); } /// /// 发送关闭节点包 /// protected void SendCloseNode() { PackHead head = PackHead.Create(); head.packlx = ServerPackAgreement.closeNode; var data = this.myType != ModuleType.WatchDog ? MonitoringAppInfo : null; GlobalMQ.instance.DeliveryAll(GlobalMQ.CreateMessage(head, data), true); head.Dispose(); } //自身主机信息应该是不变的。 暂存这个信息 MonitoringAppInfo MonitoringAppInfo => MonitoringAppInfo.GetCurrentApplicateInfo(this.myUtil.onlyId, this.myUtil.id, this.myUtil.nodeNum); /// /// 退出游戏 /// public virtual void Quit() { state = ServerState.Stoping; } #region ITimerProcessor /// /// 100毫秒定时器 /// public virtual void OnTime(int Interval) { //Debug.Log("秒级定时器:" + "," + System.DateTime.Now.Ticks); } /// /// 记录天 /// int Day = 0; /// /// 秒级定时器 /// public virtual void SecondTime() { updateServerInfo_time--; if (updateServerInfo_time == 0) { UpdateServerInfo(); } DoFps(); if (Day != DateTime.Now.Day) { Day = DateTime.Now.Day; DayInit(); } } #endregion /// /// 每一天初始化一次 /// public virtual void DayInit() { } /// /// 处理Fps的赋值 /// protected virtual void DoFps() { if (minfps < 0 || minfps > fpscount) { minfps = fpscount; //Debug.Warning("fps最低记录:" + minfps); } Fps = fpscount; fpscount = 0; } /// /// 缓存变化 /// /// protected virtual void CacheChange(WaitBeMsg msg) { var head = msg.head; if (head.otherString == null || head.otherString.Length == 0) return; Debug.Info("处理缓存更新!" + head.otherString[0]); CaCheManager.instance.UpdateKeyAsync(head.otherString[0]); } /// /// 处理其他 /// /// /// protected virtual bool HandleOtherServerPack(WaitBeMsg msg) => false; /// /// 处理模块死亡信号——意外死亡 /// /// protected virtual void ModuleDie(WaitBeMsg msg) { var data = JsonPack.GetData(msg.jsondata); if (data == null) Debug.Error("数据错误!"); else Debug.Warning("模块死亡信号:" + data.id + "," + data.nodeNum); } /// /// /// protected virtual void Ping(PackHead head, string jsondata) { ModuleUtile util = JsonPack.GetData(jsondata); if (util == null) Debug.Error("收到网络监测包数据为空!"); head.packlx = ServerPackAgreement.Pong; GlobalMQ.instance.DeliveryOne(new ServerNode(util.id, util.nodeNum), GlobalMQ.CreateMessage(head, myUtil), true); Debug.Info("发送探测包:" + myUtil.ToString()); } /// /// /// /// /// protected virtual void Pong(PackHead head, string jsondata) { ModuleUtile util = JsonPack.GetData(jsondata); if (util == null) Debug.Error("收到网络探测回包数据为空!"); else Debug.Info("Pong : " + util.ToString()); } /// /// 心跳处理包 /// /// 消息 protected virtual void Heart(WaitBeMsg msg) { PackHead head = msg.head; ServerNode node = head.sendutil; if (node == null) { Debug.Error("心跳包错误,没有发送者的描述!"); return; } if (node.Equals(myUtil)) //自己的包不处理 return; //ServerHeart.instanece.DoHeartAsync(node.id, node.nodeNum); } /// /// 节点开启信号 /// /// 消息 [System.Diagnostics.DebuggerNonUserCode] protected virtual void RecvOpenNode(WaitBeMsg msg) { PackHead head = msg.head; ModuleUtile node = head.sendutil; if (node == null) { Debug.Error("节点开启信号包错误,没有发送者的描述!"); return; } if (node.Equals(myUtil)) { return; } //Debug.Info($"接收到模块开启:{node.ToString()}"); RountingManager.instance.AddModule(node.id, node.name); if (node.id == (int)ModuleType.ConfigModule) { SendConfigPack(); } if (head.otherString == null || head.otherString.Length == 0 || head.otherString[0] != "ok") { head.packlx = ServerPackAgreement.openNode; head.otherString = new string[] { "ok" }; var data = this.myType != ModuleType.WatchDog ? MonitoringAppInfo : null; var sendmsg = GlobalMQ.CreateMessage(head, data, null, -1, -1, null, null); GlobalMQ.instance.DeliveryOne(node, sendmsg, true); } ServerHeart.instanece.AddModule(node.id, node.name, node.nodeNum); } /// /// 节点关闭信号_正常关闭 /// /// 消息 protected virtual void RecvCloseNode(WaitBeMsg msg) { ModuleUtile node = msg.head.sendutil; if (node == null) { Debug.Error("收到节点关闭信号,没有发送者的描述!"); return; } if (node.Equals(myUtil)) { //是本模块 if (node.onlyId != myUtil.onlyId) { return; } if (state == ServerState.Runing) { //检测到已经死了 //直接退出 Debug.Error("收到死完包!直接退出!"); state = ServerState.Error; return; } else return; } //模块死亡信号 ServerHeart.instanece.RemoveDie(node.id, node.nodeNum, true); Debug.Warning("收到模块关闭信号:" + node); } /// /// 处理命令 /// protected virtual void DoCommand(WaitBeMsg msg) { string[] cmds = msg.head.otherString; if (cmds == null || cmds.Length <= 0) return; Debug.Info("收到命令" + cmds[0]); switch (cmds[0]) { case "exit": Quit(); break; case "test": break; case "onlineModules": //在线的所有模块 Debug.Log("所有的在线模块"); break; case "redislocktest": break; } } /// /// DistributedLock /// protected DistributedLock dtl { get; } = new DistributedLock(1000); #region IServer /// /// 服务器状态 /// public ServerState state { get; set; } = ServerState.Close; /// /// 服务器名称 /// public string ServerName { get { return ServerConfigManager.Instance.ServerName; } } /// /// 我的模块单元 /// public ModuleUtile myUtil { get; protected set; } private ModuleType mMyType; /// /// 模块类型 /// public ModuleType myType { get { return mMyType; } } /// /// 消息处理器 /// public MessageProcessor msgProcessor; /// /// 其他配置初始化 /// public virtual void OtherConfigInit() { StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < 50; i++) { stringBuilder.Append('0'); } if (ServerConfigManager.Instance.GameConfig != null) { ServerConfigManager.Instance.GameConfig.GameGz = stringBuilder.ToString(); if (ServerConfigManager.Instance.TingCnt > 0) { foreach (var ting in ServerConfigManager.Instance.Tings) { ting.TingGz = stringBuilder.ToString(); } } } } /// /// 检查配置表是否有问题 /// /// public virtual bool CheckConfig() { return true; } /// /// 启动 /// public bool Start() { //启动中 state = ServerState.Starting; mMyType = (ModuleType)ServerConfigManager.Instance.NodeId; myUtil = new ModuleUtile(ServerConfigManager.Instance.NodeId, ServerConfigManager.Instance.NodeNum, Enum.GetName(myType.GetType(), myType), ServerConfigManager.Instance.MaxVer); TimeInfo.Instance.DayChange += DayChange; //序列化预热 PreLoadMessagePack(); GlobalDispatcher.Instance.Dispatch(GlobalMsgId.GameNameReadSuccess, ServerConfigManager.Instance.ServerName); Debug.Info($"Start ServerName:{ServerConfigManager.Instance.ServerName}"); //数据库初始化 GameDB.Instance.Init(SqlConfigCategory.Instance.GetDBSqlConfig()); //redis启动 redisManager.Start(); ClientConfig = GetConfigHead(); //存储自己的模块信息 if (!redisManager.db.HashExists(RedisDictionary.moduleNames, ServerConfigManager.Instance.NodeId.ToString())) redisManager.db.HashSet(RedisDictionary.moduleNames, ServerConfigManager.Instance.NodeId, myUtil.name); //心跳开始,并检查模块是否在线 if (!ServerHeart.instanece.Start(myType, ServerConfigManager.Instance.NodeNum)) { Debug.ImportantLog("启动失败,模块在线!"); return false; } MessagePool.tag = "" + myUtil.id + "-" + myUtil.nodeNum + "-" + myUtil.ver + "-" + myUtil.name; //模块死亡事件监听 GlobalDispatcher.Instance.AddListener(GlobalMsgId.ModuleNodeDie, DoModuleDieSign); //创建消息处理 Factory.CreateGlobalMQFactory().CreateGlobalMQ(); //启动rabbit if (!GlobalMQ.instance.StartModule(RabbitConfigCategory.Instance.GetRabbitMQConfig(), myUtil)) { Debug.Error("启动失败:A71134F4-EA97-44C0-A305-E35966622FEB"); return false; } msgProcessor = Factory.CreateMessageProcessor(); new UserSessionsManager().Register(); //重要数据启动 if (!Init()) { return false; } Debug.ImportantLog("init over!!!"); //发送开启信号 SendOpenNode(); //定时器管理 timermgr = new TimerManager(ServerConfigManager.Instance.OnTime); timermgr.Start(); //更改状态为运行中 state = ServerState.Runing; //更新服务器信息 UpdateServerInfo(true); //开始发送心跳包 ServerHeart.instanece.BeginHeart(Factory.CreateHeartPack(myUtil)); return true; } private StringBuilder logs = new StringBuilder(); private int GcCount = 0; /// /// 预热 MessagePack /// protected virtual void PreLoadMessagePack() { } private void ReLoadTable() { TableManager.Instance.ReLoadTableData(); try { ReLoadTableInit(); Debug.ImportantLog("配置重新加载成功!"); } catch (Exception e) { Debug.Error("重载配置出错!" + e.Message); TableManager.Instance.RollBack(); } } protected virtual void ReLoadTableInit() { } /// /// 主线程 /// public void Loop() { if (state == ServerState.Runing) { try { logs.Clear(); watch.Restart(); //watch.Restart(); if (IsReloadTable) { IsReloadTable = false; ReLoadTable(); } if (timermgr.GetMillScoend()) { #if DEBUG var key = Debug.StartTiming(); logs.AppendLine($"GlobalManager Loop DoTime begin"); #endif OnTime(timermgr.Interval); #if DEBUG logs.AppendLine($"GlobalManager Loop DoTime end, time: {Debug.GetRunTime(key)}"); #endif } if (timermgr.GetSecoend()) { #if DEBUG var key = Debug.StartTiming(); logs.AppendLine($"GlobalManager Loop DoTimeSecond begin"); #endif SecondTime(); #if DEBUG logs.AppendLine($"GlobalManager Loop DoTimeSecond end, time: {Debug.GetRunTime(key)}"); #endif } //消息处理 msgProcessor.Run(logs); #if DEBUG var updateKey = Debug.StartTiming(); #endif fpscount++; Update(); #if DEBUG logs.AppendLine($"Update Loop time:{Debug.GetRunTime(updateKey)}"); #endif watch.Stop(); double runtime = watch.ElapsedMilliseconds; //.ElapsedMilliseconds; if (runtime >= 100) { logs.AppendLine( $"GlobalManager Loop end, now: {DateTime.Now}, runtime: {runtime} / {watch.Elapsed.TotalMilliseconds}"); Debug.Error($"Loop runtime warning: " + logs.ToString()); } if (runtime > maxruntiming) maxruntiming = runtime; } catch (Exception e) { Debug.Error("主线程错误:" + e.ToString()); } } else if (state == ServerState.Stoping) { Close(); } } /// /// 阻塞检查,直到正常退出 /// public virtual void Close() { UUIDManager.Instance.Close(); UserSessionsManager.Instance.Dispose(); timermgr.Stop(); SendCloseNode(); ServerHeart.instanece.Close(); //ServerManager.instance.Close(); if (GlobalMQ.instance != null) GlobalMQ.instance.Close(); //保存道具日志 PropManager.Instance.Dispose(); state = ServerState.Stop; Debug.Log("模块正常退出!"); } #endregion /// /// 收到获取在线人数的请求 /// /// protected virtual void ReportPlayerOnLineData(WaitBeMsg msg) { } } }