断线重连
断线重连
备注:编程元件建立工程后,默认就包含断线重连的功能示例,可以搜索S2C_OnReconnected消息,了解其用法。
下面的例子,会介绍如何从头开始制作断线重连功能。
此外,也可以在资源社区,获取模板《断线重连示例》,体验该功能。
--需要恢复的成员local Reconnect = { camera_state=nil, ui_state=nil, change_number=0}--通过编程元件的自定义属性,获取按钮实例Idlocal elementId = System:GetScriptParentID()local far_camera_button=CustomProperty:GetCustomProperty(elementId,"远景摄像机按钮",CustomProperty.PROPERTY_TYPE.CustomUI) --远景摄像机按钮local near_camera_button=CustomProperty:GetCustomProperty(elementId,"近景摄像机按钮",CustomProperty.PROPERTY_TYPE.CustomUI) --近景角相机按钮local change_number_text=CustomProperty:GetCustomProperty(elementId,"切换次数数字",CustomProperty.PROPERTY_TYPE.CustomUI) --切换次数数字的控件
local playersInfo={}--记录全部玩家的状态信息
--客户端初始化function Reconnect:GameClientInit() --客户端初始化,注册断线重连消息 System:BindNotify(NetMsg.S2C_OnReconnected, self.S2C_OnReconnected, self)end--服务器初始化function Reconnect:GameServerInit() --服务器初始化,注册客户端请求记录信息 System:BindNotify(NetMsg.C2S_SaveClientInfo, self.OnSaveClientInfo, self) -- 注册断线重连事件。断线重连时,同步当前游戏状态给客户端 System:RegisterEvent(Events.ON_PLAYER_RECONNECTED, self.OnServerReconnected, self)
end--客户端开始时function Reconnect:GameClientOnStart() --举例:点击[远景摄像机按钮] UI:RegisterPressed(far_camera_button,function () --分别设置相机和界面的状态 Reconnect:SetCamera(1) Reconnect:SetUI(1) --向服务器发消息,记录相机信息 --注意:因为目前不能直接发送引擎结构体消息(例如Engine.Vector),所以这里发送的是状态信息。 System:SendToServer(NetMsg.C2S_SaveClientInfo, { camera_state=1, ui_state=1, } ) end) --[近景摄像机按钮]注册点击事件,功能类似 UI:RegisterPressed(near_camera_button,function () Reconnect:SetCamera(2) Reconnect:SetUI(2) System:SendToServer(NetMsg.C2S_SaveClientInfo, { camera_state=2, ui_state=2, } ) end)
end--服务器开始时function Reconnect:GameServerOnStart() --创建一个生物,方便查看效果 Creature:SpawnCreature(1114000000000005,Engine.Vector(0,500,0),Engine.Vector(1,0,0),1)
-- 获取当前登录服务器的所有玩家ID local playerIds = Character:GetAllPlayerIds() --遍历数据 for _, v in ipairs(playerIds) do local player_info={} --初始化一个表来管理记录的信息 --定义默认值 player_info.camera_state=1 player_info.ui_state=1 player_info.change_number=0 --将玩家ID作为键,玩家信息表作为值,存储到playersInfo中 playersInfo[v]=player_info System:SendToClient(v, NetMsg.S2C_OnReconnected,playersInfo[v]) --游戏开始,第一次同步初始信息给客户端 end
end
--根据状态,设置控件的显示或隐藏function Reconnect:SetUI(state) if state==1 then --远景时,显示近景按钮 UI:SetVisible({far_camera_button},false) UI:SetVisible({near_camera_button},true) elseif state==2 then --近景时,显示远景按钮 UI:SetVisible({far_camera_button},true) UI:SetVisible({near_camera_button},false) endend
--根据状态,设置相机位置和角度function Reconnect:SetCamera(state) if state==1 then --将相机挂载到目标(远) local pos=Engine.Vector(1000,500,100) local rot=Engine.Rotator(0,0,180) Camera:BindOnWorldPosition(pos,rot,0.1) print("@@## far camera 1")
elseif state==2 then --将相机挂载到目标(近) local pos=Engine.Vector(250,500,100) local rot=Engine.Rotator(0,0,180) Camera:BindOnWorldPosition(pos,rot,0.1) print("@@## near camera 2") end
end
--服务器,收到客户端请求,记录信息function Reconnect:OnSaveClientInfo(msgId, msg, playerId) if msg.camera_state~=nil then -- 直接更新消息中包含的键 for key, value in pairs(msg) do playersInfo[playerId][key] = value end end --记录切换次数 playersInfo[playerId].change_number=playersInfo[playerId].change_number+1 --当服务器处理完成,返回给客户端数据 System:SendToClient(playerId, NetMsg.S2C_OnReconnected,playersInfo[playerId])
end
-- 断线重连逻辑,服务器下发需要同步的信息function Reconnect:OnServerReconnected(playerId, levelId) System:SendToClient(playerId, NetMsg.S2C_OnReconnected, playersInfo[playerId])end
-- 客户端,收到服务器下发的数据function Reconnect:S2C_OnReconnected(msgId, msg) if msg~=nil then for key,value in pairs(msg) do self[key]=value end --设置相机 self:SetCamera(self.camera_state) --设置文本 UI:SetText({change_number_text},tostring(self.change_number)) --设置按钮 self:SetUI(self.ui_state)
end
end
return Reconnect