/// <summary> /// 在多个线程内部循环调用 /// </summary> public void ProcessCmdPackets(Queue <CmdPacket> ls) { //dictInPackets.Values值的个数可能会变化,每次处理先保存好最大个数 //同时给出20个冗余数量 int maxCount = dictInPackets.Values.Count + 20; for (int n = 0; n < maxCount; n++) { TCPInPacket tcpInPacket = GetNextTcpInPacket(n); //这意味着列表数据包变少了 if (null == tcpInPacket) { break; } ls.Clear(); if (tcpInPacket.PopCmdPackets(ls)) //判断是否取到了指令列表 { try { while (ls.Count > 0) { CmdPacket cmdPacket = ls.Dequeue(); //接收到了完整的命令包 TCPOutPacket tcpOutPacket = null; TCPProcessCmdResults result = TCPProcessCmdResults.RESULT_FAILED; result = TCPCmdHandler.ProcessCmd(this, tcpInPacket.CurrentSocket, tcpClientPool, tcpRandKey, tcpOutPacketPool, cmdPacket.CmdID, cmdPacket.Data, cmdPacket.Data.Length, out tcpOutPacket); if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { //向登陆客户端返回数据 socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket); } else if (result == TCPProcessCmdResults.RESULT_FAILED)//解析失败, 直接关闭连接 { if (cmdPacket.CmdID != (int)TCPGameServerCmds.CMD_LOG_OUT) { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); } SysConOut.WriteLine("========================ProcessCmdPackets CloseSocket================"); // Console.WriteLine("========================ProcessCmdPackets CloseSocket================"); //这儿需要关闭链接--->这样关闭对吗? socketListener.CloseSocket(tcpInPacket.CurrentSocket); break; } } } finally { //处理结束之后设置相关标志位 tcpInPacket.OnThreadDealingComplete(); } } } }
public void ProcessCmdPackets(Queue <CmdPacket> ls) { int maxCount = this.dictInPackets.Values.Count + 20; for (int i = 0; i < maxCount; i++) { TCPInPacket tcpInPacket = this.GetNextTcpInPacket(i); if (null == tcpInPacket) { break; } ls.Clear(); if (tcpInPacket.PopCmdPackets(ls)) { try { while (ls.Count > 0) { CmdPacket cmdPacket = ls.Dequeue(); TCPOutPacket tcpOutPacket = null; TCPProcessCmdResults result = TCPCmdHandler.ProcessCmd(this, tcpInPacket.CurrentSocket, this.tcpClientPool, this.tcpRandKey, this.tcpOutPacketPool, cmdPacket.CmdID, cmdPacket.Data, cmdPacket.Data.Length, out tcpOutPacket); if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { this.socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket, true); } else { if (result == TCPProcessCmdResults.RESULT_FAILED) { if (cmdPacket.CmdID != 22) { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket, false)), null, true); } this.socketListener.CloseSocket(tcpInPacket.CurrentSocket, ""); break; } if (result == TCPProcessCmdResults.RESULT_DATA_CLOSE && null != tcpOutPacket) { this.socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket, true); tcpInPacket.CurrentSocket.DelayClose = 250; } } } } finally { tcpInPacket.OnThreadDealingComplete(); } } } }
public void run() { int cmdID = 0; long processTime = 0L; long processWaitTime = 0L; if (Monitor.TryEnter(this.session.Lock)) { try { long processBeginTime = TimeUtil.NowEx(); processWaitTime = processBeginTime - this.beginTime; TCPCmdWrapper wrapper = this.session.getNextTCPCmdWrapper(); if (null != wrapper) { try { TCPCmdHandler.ProcessCmd(wrapper.TcpMgr, wrapper.TMSKSocket, wrapper.TcpClientPool, wrapper.TcpRandKey, wrapper.Pool, wrapper.NID, wrapper.Data, wrapper.Count); } catch (Exception ex) { DataHelper.WriteFormatExceptionLog(ex, string.Format("指令处理错误:{0},{1}", Global.GetDebugHelperInfo(wrapper.TMSKSocket), (TCPGameServerCmds)wrapper.NID), false, false); } ProcessSessionTask.processCmdNum += 1L; processTime = TimeUtil.NowEx() - processBeginTime; ProcessSessionTask.processTotalTime += processWaitTime + processTime; cmdID = wrapper.NID; wrapper.release(); wrapper = null; } } catch (Exception ex) { throw ex; } finally { Monitor.Exit(this.session.Lock); } if (cmdID > 0) { TCPManager.RecordCmdDetail2(cmdID, processTime, processWaitTime); } } else { TCPManager.getInstance().taskExecutor.scheduleExecute(this, 5L); } }
/// <summary> /// 命令包接收完毕后的回调事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private bool TCPCmdPacketEvent(object sender) { TCPInPacket tcpInPacket = sender as TCPInPacket; //接收到了完整的命令包 TCPOutPacket tcpOutPacket = null; TCPProcessCmdResults result = TCPProcessCmdResults.RESULT_FAILED; GameServerClient client = null; if (!gameServerClients.TryGetValue(tcpInPacket.CurrentSocket, out client)) { LogManager.WriteLog(LogTypes.Error, string.Format("未建立会话或会话已关闭: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); return(false); } //接收到了完整的命令包 long processBeginTime = TimeUtil.NowEx(); result = TCPCmdHandler.ProcessCmd(client, DBMgr, tcpOutPacketPool, tcpInPacket.PacketCmdID, tcpInPacket.GetPacketBytes(), tcpInPacket.PacketDataSize, out tcpOutPacket); long processTime = (TimeUtil.NowEx() - processBeginTime); if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { //向对方发送数据 socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket); } else if (result == TCPProcessCmdResults.RESULT_FAILED)//解析失败, 直接关闭连接 { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); //socketListener.CloseSocket(tcpInPacket.CurrentSocket); return(false); } lock (cmdMoniter) //锁定命令监控对象 { int cmdID = tcpInPacket.PacketCmdID; PorcessCmdMoniter moniter = null; if (!cmdMoniter.TryGetValue(cmdID, out moniter)) { moniter = new PorcessCmdMoniter(cmdID, processTime); cmdMoniter.Add(cmdID, moniter); } moniter.onProcessNoWait(processTime); } return(true); }
private bool TCPCmdPacketEvent(object sender) { TCPInPacket tcpInPacket = sender as TCPInPacket; TCPOutPacket tcpOutPacket = null; GameServerClient client = null; bool result2; if (!this.gameServerClients.TryGetValue(tcpInPacket.CurrentSocket, out client)) { LogManager.WriteLog(LogTypes.Error, string.Format("未建立会话或会话已关闭: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket)), null, true); result2 = false; } else { TCPManager.CurrentClient = client; long processBeginTime = TimeUtil.NowEx(); TCPProcessCmdResults result = TCPCmdHandler.ProcessCmd(client, this.DBMgr, this.tcpOutPacketPool, (int)tcpInPacket.PacketCmdID, tcpInPacket.GetPacketBytes(), tcpInPacket.PacketDataSize, out tcpOutPacket); long processTime = TimeUtil.NowEx() - processBeginTime; if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { this.socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket); } else if (result == TCPProcessCmdResults.RESULT_FAILED) { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket)), null, true); return(false); } lock (TCPManager.cmdMoniter) { int cmdID = (int)tcpInPacket.PacketCmdID; PorcessCmdMoniter moniter = null; if (!TCPManager.cmdMoniter.TryGetValue(cmdID, out moniter)) { moniter = new PorcessCmdMoniter(cmdID, processTime); TCPManager.cmdMoniter.Add(cmdID, moniter); } moniter.onProcessNoWait(processTime); } TCPManager.CurrentClient = null; result2 = true; } return(result2); }
private bool TCPCmdPacketEvent(object sender, int doType) { TCPInPacket tcpInPacket = sender as TCPInPacket; if (0 == doType) { int thisTimeCheckTicks = 0; int checkErrorCode = 0; byte[] bytesData = this.CheckClientDataValid((int)tcpInPacket.PacketCmdID, tcpInPacket.GetPacketBytes(), tcpInPacket.PacketDataSize, tcpInPacket.LastCheckTicks, out thisTimeCheckTicks, out checkErrorCode); if (null == bytesData) { TMSKSocket _s = tcpInPacket.CurrentSocket; string uid = (_s != null) ? GameManager.OnlineUserSession.FindUserID(_s) : "socket is nil"; LogManager.WriteLog(LogTypes.Error, string.Format("校验客户端发送的指令数据完整性失败: {0},{1}, 错误码:{2}, uid={3}, 关闭连接", new object[] { (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket, false), checkErrorCode, uid }), null, true); return(false); } tcpInPacket.LastCheckTicks = thisTimeCheckTicks; tcpInPacket.CurrentSocket.ClientCmdSecs = thisTimeCheckTicks; TCPSession session = null; if (null != tcpInPacket.CurrentSocket) { session = tcpInPacket.CurrentSocket.session; } if (null == session) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket, false), checkErrorCode), null, true); return(false); } int posCmdNum = 0; session.CheckCmdNum((int)tcpInPacket.PacketCmdID, (long)thisTimeCheckTicks, out posCmdNum); if (posCmdNum > 0) { int banSpeedUpMinutes = GameManager.PlatConfigMgr.GetGameConfigItemInt("ban-speed-up-minutes2", 10); GameClient client = GameManager.ClientMgr.FindClient(tcpInPacket.CurrentSocket); if (null != client) { if (GameManager.PlatConfigMgr.GetGameConfigItemInt("ban_speed_up_delay", 0) == 0 || client.CheckCheatData.ProcessBooster) { GameManager.ClientMgr.NotifyImportantMsg(this.MySocketListener, this.tcpOutPacketPool, client, StringUtil.substitute(GLang.GetLang(663, new object[0]), new object[] { banSpeedUpMinutes }), GameInfoTypeIndexes.Error, ShowGameInfoTypes.HintAndBox, 0); BanManager.BanRoleName(Global.FormatRoleName(client, client.ClientData.RoleName), banSpeedUpMinutes, 1); LogManager.WriteLog(LogTypes.Error, string.Format("通过POSITION指令判断客户端加速: {0}, 指令个数:{1}, 断开连接", Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket, false), posCmdNum), null, true); return(false); } if (client.CheckCheatData.ProcessBoosterTicks == 0L) { client.CheckCheatData.ProcessBoosterTicks = TimeUtil.NOW(); } } } TCPOutPacket tcpOutPacket = null; long processBeginTime = TimeUtil.NowEx(); TCPProcessCmdResults result = TCPCmdHandler.ProcessCmd(this, tcpInPacket.CurrentSocket, this.tcpClientPool, this.tcpRandKey, this.tcpOutPacketPool, (int)tcpInPacket.PacketCmdID, bytesData, tcpInPacket.PacketDataSize - 1 - 4, out tcpOutPacket); long processTime = TimeUtil.NowEx() - processBeginTime; if (GameManager.StatisticsMode > 0 || processTime > 50L || result == TCPProcessCmdResults.RESULT_FAILED) { TCPManager.RecordCmdDetail((int)tcpInPacket.PacketCmdID, processTime, (long)tcpInPacket.PacketDataSize, result); } if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { this.socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket, true); } else { if (result == TCPProcessCmdResults.RESULT_FAILED) { if (tcpInPacket.PacketCmdID != 22) { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket, false)), null, true); } return(false); } if (result == TCPProcessCmdResults.RESULT_DATA_CLOSE && null != tcpOutPacket) { this.socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket, true); tcpInPacket.CurrentSocket.DelayClose = 250; } } } else { if (1 != doType) { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令时类型未知: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket, false)), null, true); return(false); } this.DirectSendPolicyFileData(tcpInPacket); } return(true); }
/// <summary> /// 命令包接收完毕后的回调事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private bool TCPCmdPacketEvent(object sender, int doType) { TCPInPacket tcpInPacket = sender as TCPInPacket; if (0 == doType) //正常的登录指令包 { int thisTimeCheckTicks = 0; int checkErrorCode = 0; if (0xffff == tcpInPacket.PacketCmdID) { String cmdData = new UTF8Encoding().GetString(tcpInPacket.GetPacketBytes(), 0, tcpInPacket.PacketDataSize); if (cmdData == "serveripinfo") { String strinfo = string.Format("{0}_{1}", ServerPort, Global.GetLocalAddressIPs()); byte [] arrSendData = Encoding.UTF8.GetBytes(strinfo); if (null != arrSendData) { tcpInPacket.CurrentSocket.Send(arrSendData, arrSendData.Length, SocketFlags.None); } } return(false); } //这里实际上是有一个指令流的拷贝,占用的很零碎的内存,这个是否考虑使用内存池???? byte[] bytesData = CheckClientDataValid(tcpInPacket.PacketCmdID, tcpInPacket.GetPacketBytes(), tcpInPacket.PacketDataSize, tcpInPacket.LastCheckTicks, out thisTimeCheckTicks, out checkErrorCode); if (null != bytesData) { tcpInPacket.LastCheckTicks = thisTimeCheckTicks; //记忆此次的心跳数据 //#if false if (UseWorkerPool) { //杰隆的异步处理指令入口代码 TCPCmdWrapper wrapper = TCPCmdWrapper.Get(this, tcpInPacket.CurrentSocket, tcpClientPool, tcpRandKey, tcpOutPacketPool, tcpInPacket.PacketCmdID, bytesData, tcpInPacket.PacketDataSize - 1 - 4); TCPSession session = null; if (GameManager.FlagOptimizeLock3) { if (null != tcpInPacket.CurrentSocket) { session = tcpInPacket.CurrentSocket.session; } if (null == session) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } else { lock (tcpSessions) { if (!tcpSessions.TryGetValue(tcpInPacket.CurrentSocket, out session)) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } } int posCmdNum = 0; session.addTCPCmdWrapper(wrapper, out posCmdNum); if (posCmdNum > 0) { int banSpeedUpMinutes = GameManager.PlatConfigMgr.GetGameConfigItemInt(PlatConfigNames.BanSpeedUpMinutes2, 10); //加速禁止登陆的时间 GameClient client = GameManager.ClientMgr.FindClient(tcpInPacket.CurrentSocket); if (null != client) { GameManager.ClientMgr.NotifyImportantMsg(this.MySocketListener, tcpOutPacketPool, client, StringUtil.substitute(Global.GetLang("本游戏禁止使用加速软件,{0}分钟内将禁止登陆!"), banSpeedUpMinutes), GameInfoTypeIndexes.Error, ShowGameInfoTypes.HintAndBox); BanManager.BanRoleName(Global.FormatRoleName(client, client.ClientData.RoleName), banSpeedUpMinutes); } LogManager.WriteLog(LogTypes.Error, string.Format("通过POSITION指令判断客户端加速: {0}, 指令个数:{1}, 断开连接", Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), posCmdNum)); return(false); } taskExecutor.execute(new ProcessSessionTask(session)); } //#else else { TCPSession session = null; if (GameManager.FlagOptimizeLock3) { if (null != tcpInPacket.CurrentSocket) { session = tcpInPacket.CurrentSocket.session; } if (null == session) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } else { lock (tcpSessions) { if (!tcpSessions.TryGetValue(tcpInPacket.CurrentSocket, out session)) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } } int posCmdNum = 0; session.CheckCmdNum(tcpInPacket.PacketCmdID, out posCmdNum); if (posCmdNum > 0) { int banSpeedUpMinutes = GameManager.PlatConfigMgr.GetGameConfigItemInt(PlatConfigNames.BanSpeedUpMinutes2, 10); //加速禁止登陆的时间 GameClient client = GameManager.ClientMgr.FindClient(tcpInPacket.CurrentSocket); if (null != client) { if (client.CheckCheatData.ProcessBooster) { GameManager.ClientMgr.NotifyImportantMsg(this.MySocketListener, tcpOutPacketPool, client, StringUtil.substitute(Global.GetLang("本游戏禁止使用加速软件,{0}分钟内将禁止登陆!"), banSpeedUpMinutes), GameInfoTypeIndexes.Error, ShowGameInfoTypes.HintAndBox); BanManager.BanRoleName(Global.FormatRoleName(client, client.ClientData.RoleName), banSpeedUpMinutes); LogManager.WriteLog(LogTypes.Error, string.Format("通过POSITION指令判断客户端加速: {0}, 指令个数:{1}, 断开连接", Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), posCmdNum)); return(false); } else if (client.CheckCheatData.ProcessBoosterTicks == 0) { client.CheckCheatData.ProcessBoosterTicks = TimeUtil.NOW(); } } } TCPOutPacket tcpOutPacket = null; TCPProcessCmdResults result = TCPProcessCmdResults.RESULT_FAILED; long processBeginTime = TimeUtil.NowEx(); if (tcpInPacket.PacketCmdID > 30000) { result = CCTCPCmdHandler.CCProcessCmd(this, tcpInPacket.CurrentSocket, tcpClientPool, tcpRandKey, tcpOutPacketPool, tcpInPacket.PacketCmdID, bytesData, tcpInPacket.PacketDataSize - 1 - 4, out tcpOutPacket); } else { result = TCPCmdHandler.ProcessCmd(this, tcpInPacket.CurrentSocket, tcpClientPool, tcpRandKey, tcpOutPacketPool, tcpInPacket.PacketCmdID, bytesData, tcpInPacket.PacketDataSize - 1 - 4, out tcpOutPacket); } long processTime = (TimeUtil.NowEx() - processBeginTime); if (GameManager.StatisticsMode > 0 || processTime > 50 || result == TCPProcessCmdResults.RESULT_FAILED) { RecordCmdDetail(tcpInPacket.PacketCmdID, processTime, tcpInPacket.PacketDataSize, result); } if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { // Console.WriteLine("===>>> tcpOutPacket==== " + tcpOutPacket.PacketCmdID.ToString()); //向登陆客户端返回数据 socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket); } else if (result == TCPProcessCmdResults.RESULT_FAILED)//解析失败, 直接关闭连接 { if (tcpInPacket.PacketCmdID != (int)TCPGameServerCmds.CMD_LOG_OUT) { SysConOut.WriteLine(string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); } return(false); } } //#endif } else { var _s = tcpInPacket.CurrentSocket; string uid = _s != null?GameManager.OnlineUserSession.FindUserID(_s) : "socket is nil"; SysConOut.WriteLine(string.Format("校验客户端发送的指令数据完整性失败: {0},{1}, 错误码:{2}, uid={3}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode, uid)); LogManager.WriteLog(LogTypes.Error, string.Format("校验客户端发送的指令数据完整性失败: {0},{1}, 错误码:{2}, uid={3}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode, uid)); return(false); } } else if (1 == doType) //正常的登录指令包//策略验证请求 { //直接发送策略数据 DirectSendPolicyFileData(tcpInPacket); } else { SysConOut.WriteLine(string.Format("解析并执行命令时类型未知: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令时类型未知: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); //socketListener.CloseSocket(tcpInPacket.CurrentSocket); return(false); } return(true); }
public void run() { // lock (session.Lock) // { // // } int cmdID = 0; long processTime = 0L; long processWaitTime = 0L; //因为业务层处理时未做同步,暂时锁会话,保证每个玩家的指令处理时线性的 if (Monitor.TryEnter(session.Lock)) { try { long processBeginTime = TimeUtil.NowEx(); processWaitTime = processBeginTime - beginTime; TCPCmdWrapper wrapper = session.getNextTCPCmdWrapper(); if (null != wrapper) { try { TCPCmdHandler.ProcessCmd(wrapper.TcpMgr, wrapper.TMSKSocket, wrapper.TcpClientPool, wrapper.TcpRandKey, wrapper.Pool, wrapper.NID, wrapper.Data, wrapper.Count); } catch (Exception ex) { DataHelper.WriteFormatExceptionLog(ex, string.Format("指令处理错误:{0},{1}", Global.GetDebugHelperInfo(wrapper.TMSKSocket), (TCPGameServerCmds)wrapper.NID), false); } processCmdNum++; processTime = (TimeUtil.NowEx() - processBeginTime); processTotalTime += (processWaitTime + processTime); cmdID = wrapper.NID; wrapper.release(); wrapper = null; } } catch (Exception ex) { throw ex; } finally { Monitor.Exit(session.Lock); } if (cmdID > 0) { TCPManager.RecordCmdDetail2(cmdID, processTime, processWaitTime); } } else { //如果当session有指令正在处理,把当前指令重新丢进队列,延迟5毫秒处理,防止同一session占用过多线程,保证资源合理利用 TCPManager.getInstance().taskExecutor.scheduleExecute(this, 5); } }
/// <summary> /// 命令包接收完毕后的回调事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private bool TCPCmdPacketEvent(object sender, int doType) { TCPInPacket tcpInPacket = sender as TCPInPacket; if (0 == doType) //正常的登录指令包 { int thisTimeCheckTicks = 0; int checkErrorCode = 0; //这里实际上是有一个指令流的拷贝,占用的很零碎的内存,这个是否考虑使用内存池???? byte[] bytesData = CheckClientDataValid(tcpInPacket.PacketCmdID, tcpInPacket.GetPacketBytes(), tcpInPacket.PacketDataSize, tcpInPacket.LastCheckTicks, out thisTimeCheckTicks, out checkErrorCode); if (null != bytesData) { tcpInPacket.LastCheckTicks = thisTimeCheckTicks; //记忆此次的心跳数据 //#if false if (UseWorkerPool) { //杰隆的异步处理指令入口代码 TCPCmdWrapper wrapper = TCPCmdWrapper.Get(this, tcpInPacket.CurrentSocket, tcpClientPool, tcpRandKey, tcpOutPacketPool, tcpInPacket.PacketCmdID, bytesData, tcpInPacket.PacketDataSize - 1 - 4); TCPSession session = null; if (GameManager.FlagOptimizeLock3) { if (null != tcpInPacket.CurrentSocket) { session = tcpInPacket.CurrentSocket.session; } if (null == session) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } else { lock (tcpSessions) { if (!tcpSessions.TryGetValue(tcpInPacket.CurrentSocket, out session)) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } } int posCmdNum = 0; session.addTCPCmdWrapper(wrapper, out posCmdNum); if (posCmdNum > 0) { int banSpeedUpMinutes = GameManager.GameConfigMgr.GetGameConfigItemInt("ban-speed-up-minutes2", 10); //加速禁止登陆的时间 GameClient client = GameManager.ClientMgr.FindClient(tcpInPacket.CurrentSocket); if (null != client) { GameManager.ClientMgr.NotifyImportantMsg(this.MySocketListener, tcpOutPacketPool, client, StringUtil.substitute(Global.GetLang("本游戏禁止使用加速软件,{0}分钟内将禁止登陆!"), banSpeedUpMinutes), GameInfoTypeIndexes.Error, ShowGameInfoTypes.HintAndBox); BanManager.BanRoleName(Global.FormatRoleName(client, client.ClientData.RoleName), banSpeedUpMinutes); } LogManager.WriteLog(LogTypes.Error, string.Format("通过POSITION指令判断客户端加速: {0}, 指令个数:{1}, 断开连接", Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), posCmdNum)); return(false); } taskExecutor.execute(new ProcessSessionTask(session)); } //#else else { TCPSession session = null; if (GameManager.FlagOptimizeLock3) { if (null != tcpInPacket.CurrentSocket) { session = tcpInPacket.CurrentSocket.session; } if (null == session) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } else { lock (tcpSessions) { if (!tcpSessions.TryGetValue(tcpInPacket.CurrentSocket, out session)) { LogManager.WriteLog(LogTypes.Error, string.Format("未与客户端建立会话: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } } int posCmdNum = 0; session.CheckCmdNum(tcpInPacket.PacketCmdID, out posCmdNum); if (posCmdNum > 0) { int banSpeedUpMinutes = GameManager.GameConfigMgr.GetGameConfigItemInt("ban-speed-up-minutes2", 10); //加速禁止登陆的时间 GameClient client = GameManager.ClientMgr.FindClient(tcpInPacket.CurrentSocket); if (null != client) { GameManager.ClientMgr.NotifyImportantMsg(this.MySocketListener, tcpOutPacketPool, client, StringUtil.substitute(Global.GetLang("本游戏禁止使用加速软件,{0}分钟内将禁止登陆!"), banSpeedUpMinutes), GameInfoTypeIndexes.Error, ShowGameInfoTypes.HintAndBox); BanManager.BanRoleName(Global.FormatRoleName(client, client.ClientData.RoleName), banSpeedUpMinutes); } LogManager.WriteLog(LogTypes.Error, string.Format("通过POSITION指令判断客户端加速: {0}, 指令个数:{1}, 断开连接", Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), posCmdNum)); return(false); } TCPOutPacket tcpOutPacket = null; long processBeginTime = TimeUtil.NowEx(); TCPProcessCmdResults result = TCPCmdHandler.ProcessCmd(this, tcpInPacket.CurrentSocket, tcpClientPool, tcpRandKey, tcpOutPacketPool, tcpInPacket.PacketCmdID, bytesData, tcpInPacket.PacketDataSize - 1 - 4, out tcpOutPacket); long processTime = (TimeUtil.NowEx() - processBeginTime); if (GameManager.StatisticsMode > 0 || processTime > 50 || result == TCPProcessCmdResults.RESULT_FAILED) { lock (ProcessSessionTask.cmdMoniter) //锁定命令监控对象 { int cmdID = tcpInPacket.PacketCmdID; PorcessCmdMoniter moniter = null; if (!ProcessSessionTask.cmdMoniter.TryGetValue(cmdID, out moniter)) { moniter = new PorcessCmdMoniter(cmdID, processTime); ProcessSessionTask.cmdMoniter.Add(cmdID, moniter); } moniter.onProcessNoWait(processTime, result); } } if (result == TCPProcessCmdResults.RESULT_DATA && null != tcpOutPacket) { //向登陆客户端返回数据 socketListener.SendData(tcpInPacket.CurrentSocket, tcpOutPacket); } else if (result == TCPProcessCmdResults.RESULT_FAILED)//解析失败, 直接关闭连接 { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令失败: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); return(false); } } //#endif } else { LogManager.WriteLog(LogTypes.Error, string.Format("校验客户端发送的指令数据完整性失败: {0},{1}, 错误码:{2}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket), checkErrorCode)); return(false); } } else if (1 == doType) //正常的登录指令包//策略验证请求 { //直接发送策略数据 DirectSendPolicyFileData(tcpInPacket); } else { LogManager.WriteLog(LogTypes.Error, string.Format("解析并执行命令时类型未知: {0},{1}, 关闭连接", (TCPGameServerCmds)tcpInPacket.PacketCmdID, Global.GetSocketRemoteEndPoint(tcpInPacket.CurrentSocket))); //socketListener.CloseSocket(tcpInPacket.CurrentSocket); return(false); } return(true); }