跳转到内容

断线重连

断线重连

备注:编程元件建立工程后,默认就包含断线重连的功能示例,可以搜索S2C_OnReconnected消息,了解其用法。
下面的例子,会介绍如何从头开始制作断线重连功能。
此外,也可以在资源社区,获取模板《断线重连示例》,体验该功能。

--需要恢复的成员
local Reconnect = {
camera_state=nil,
ui_state=nil,
change_number=0
}
--通过编程元件的自定义属性,获取按钮实例Id
local 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)
end
end
--根据状态,设置相机位置和角度
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