--[[ TCP 断开 ,包括 重新登录和 --]] local TCPReconnectManager = {} local private = { reconnectLevelID = -1 , -- 需要进入的场景 reconnectRandomSeed = 0, --需要进入的场景时用的随机数 cacheBattleFrames = {}, -- 缓存的大补帧数据 } local EventSystem = require('Event/EventSystem') local reconnect_pb = require "Proto/battle_reconnect_pb" function TCPReconnectManager.Init() NetManager.RegisterMsgCB(MessageEnums.MessageG2CInitFubenReConnected, private.OnG2CInitFubenReConnected) end -- 当TCP断开时 function TCPReconnectManager.OnDisconnected() if LevelManager.IsInLevelWatchBattle() then return -- 在观战中 ,不做任何处理 end --关闭KCP连接 KCPTransport.Close() --保存还没有处理的帧数据,放入到main的处理队列中 ;注意:队列千万别被清理掉 if BattleDataGetter.IsSyncLevel() then LogicUpdateManager.GetFrameDataFromKCPCache(true) end local endFrameLen = BattleExt.GetServerMsgCount() KCPTransport.ClearKCPData() BattleExt.SetServerMsgCount(endFrameLen) --关闭主循环 if BattleDataGetter.IsSyncLevel() then logging.crit(LTAG.CRIT, "TCP -1/3 :TCP OffOnline start reconnect,FrameCount =" , BattleExt.GetServerMsgCount()) LogicUpdateManager.StopFightUpdate() EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]TCPDisconnect", endFrameLen) end end --tcp 自动重连成功后 (在战斗场景中) function TCPReconnectManager.OnReconnected() local endLength = 0 if MultiReconnectManager.IsInBattle() then endLength = BattleExt.GetServerMsgCount() --MultiplayManager.CurConnectType = LuaConst.SyncConnectType.TCPReconnectInBattle -- 此时设置这个值有个要处理的case:当战斗已结束时,是没有后续的重连步骤了,这个CurConnectType需要在某个地方清理。 else endLength = 0 end MultiplayManager.CurConnectType = LuaConst.SyncConnectType.TCPReconnectInBattle MDL.Login.isReConnect = true -- 菊花 MDL.Login.SendEnterWorld(MultiReconnectManager.IsInBattle(),endLength) logging.crit(LTAG.CRIT, "TCP 0/3 :TCP Reconnected ,SendEnterWorld ,endLength=" ,endLength) --关闭KCP,防止:“发ping,并自动重连”,不要误走了kcp的断线重连 ,要按照tcp断线重连搞【断开的时候已经关闭了,这就不用关了】 --KCPTransport.Close() EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]TCPReconnected", endLength) table.clear(private.cacheBattleFrames) end --[[tcp 自动重连失败后 function TCPReconnectManager.ReconnectFailed(callBack) callBack() end--]] --部分协议 function private.OnG2CInitFubenReConnected(msg) if KCPTransport.reloginStop then logging.error(LTAG.ERROR, "[gws]: when InitFubenReConnected come , kcp is disconnect, tcp is connect ,the kcp timeOut panel is opening") EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]TCPReconnectNoRoomReturn") return end --print('OnG2CInitFubenReConnected', msg.IsFullFrameData, msg.battlexInfo.ip) --print('OnG2CInitFubenReConnected', msg) private.reconnectLevelID = msg.initScene.mapCfgId private.reconnectRandomSeed = msg.initScene.randomSeed local connectInfo = msg.battlexInfo local ip = connectInfo.ip local port = connectInfo.port local roomId = connectInfo.battleRoomId local playerId = connectInfo.playerId local gRoomID = connectInfo.gRoomId local serverID = connectInfo.serverId MultiplayManager.SetServerID(serverID) --重新进入场景时的特殊处理 if not MultiReconnectManager.IsInBattle() and MultiplayManager.CurConnectType ~= LuaConst.SyncConnectType.TCPReconnectInBattle then MultiplayManager.SetKCPConnectInfo(ip,port,roomId,playerId,gRoomID, connectInfo.agentInfo) MultiplayManager.HandleInitFubenInfo(msg.initScene , true) BattleExt.KCPFilterTankInit() -- 重置帧命令过滤功能,开始处理帧 SaveSyncBattleInfoManager.Init(msg.initScene) EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]InitFubenReconnected" ,1) LogicUpdateManager.ResetData() MultiplayManager.CurConnectType = LuaConst.SyncConnectType.TCPReconnectOutBattle else local isFairLevel = LevelManager.IsFairLevel() for _,battleRoomRoleInfo in ipairs(msg.initScene.roleList) do if LevelPlayerManager.PlayersArmyTable[battleRoomRoleInfo.playerID] == nil then LevelPlayerManager.SetSyncPlayerArmyTable(battleRoomRoleInfo, isFairLevel) logging.crit(LTAG.CRIT, "[gws]: TCP断线重连 ,发现中途有玩家进入,丢失过newplayer,现在重新添加回来!playerID = ", battleRoomRoleInfo.playerID) end end EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]InitFubenReconnected",2) end KCPTransport.Connect(ip ,port ,roomId ,playerId ) MultiReconnectManager.SetNeedWaitReconnectDone(true) logging.crit(LTAG.CRIT,"TCP 1/3 :获取InitFubenReconnect,开场随机数 ,玩家信息等。 kcp 开始连接。。。 ") MultiplayManager.IsFromStartEnter = false --如果是在战斗中,不要切换场景,连接成功后直接请求二次补帧 --收到CmdB2CConnectDone消息全后,切换场景 --重新进入场景时的特殊处理,IsNotInBattle表示进程是重新启动而不是在同步战斗中恢复连接,按正常登录流程处理 if not MultiReconnectManager.IsInBattle() then SDKUtil.OnRoleEnterScene() end end -- 收到kcp连接成功后的函数 ; 不是在战斗内重连(需要loading场景) function TCPReconnectManager.OutBattleReconnect() logging.crit(LTAG.CRIT,"TCP-out 2/3 : ,kcp连接成功,开始切换场景 SwitchLevel ") if private.reconnectRandomSeed == nil or private.reconnectRandomSeed == 0 then logging.error(LTAG.ERROR, "[gws]: 重连:服务器下发的随机种子是空的") end LevelManager.SwitchLevel(private.reconnectLevelID, private.reconnectRandomSeed, false, false) end --收到大补帧数据 function TCPReconnectManager.OnBattleFrameDatas(msg) table.insert(private.cacheBattleFrames, msg.BattleData) if not msg.IsEnd then return end local times = #private.cacheBattleFrames -- 几次发完 local battleFrameBytes = table.concat(private.cacheBattleFrames) local frameCount = BattleExt.ParseBattleReconnectFrameData(battleFrameBytes, true) -- 补帧帧总量 table.clear(private.cacheBattleFrames) EventSystem.Dispatch(EventID.BI_LevelMiddle,BIManager.BIType.SyncBattle,"[sync]TCPRecontGetAllFrame",frameCount,times) logging.crit(LTAG.CRIT, "TCP 3/3 :收到补帧,FrameCount =" , BattleExt.GetServerMsgCount()) if MultiReconnectManager.IsInBattle() then -- 如果是战斗内,则开始update LogicUpdateManager.StartFightUpdate() if GameAppInfo.IsVersionGreaterThan113100() then LogicUpdateManager.GetFrameDataFromKCPCache(true) end else -- 即TCP战斗外的断线重连 LogicUpdateManager.SetServerReplenishFrame(KCPTransport.GetCurserverFrame()) -- 二次补帧数据也需要快进 。战斗内断线重连的不需要 LevelManager.EnterSyncLevel() -- 这句代码在特殊情况下有问题,但是这种特殊case在玩家线上未遇到。这个及其特殊case:当在loading时(未到补帧)TCP断线重连,则打乱正常进入流程了。 --else -- logging.error(LTAG.ERROR, "[gws] : TCP 断线重连出现了问题 。TCP 重连时 数据设置有问题。CurConnectType =", MultiplayManager.CurConnectType) end --在这可以断定断线重连重连接上来了 ,此时需要设置下次断线为战斗中 MultiReconnectManager.SetInBattleReconnect(true) MultiplayManager.CurConnectType = LuaConst.SyncConnectType.None end return TCPReconnectManager