跳转到内容

客户端-服务器通信写法

客户端-服务器通信写法

注意:在编程元件方案中,(除非另行标明)创作者必须使用客户端-服务器模式来进行通信。

注意:Lua脚本会默认同时在客户端与服务器运行,因此需要自行处理客户端/服务器环境的区分。

--在编程元件的使用过程中,可以使用客户端-服务器模式(C/S模式)方式来进行通信。
--下面是一个例子(也可以在默认的新建工程模版中找到):
--步骤1:首先定义网络协议(消息),例如,在GameEntry中定义
NetMsg = {
OnSeverLog = 1000, -- 服务端日志打印
}
--步骤2:发送消息
--这里的例子是,服务器发送消息到全部客户端(SendToAllClients),类似的消息函数还有SendToClient,SendToServer
--下面是ServerLog函数的实现
local function ServerLog(...)
printLog(...)
-- 是否将服务端日志发送至客户端
local PrintToClient = true
if PrintToClient then
System:SendToAllClients(
NetMsg.SeverLog, --第一个参数是消息id
{...} --第二个参数是消息内容,这里的{...}是可变参数列表
)
end
end
--步骤3:接收消息一方,注册网络协议
--这里的例子是,在游戏开始时,客户端注册网络协议(一般客户端接受消息,在GameClient:OnStart()中注册;服务器接受消息,在GameServer:OnStart()中注册)
function GameClient:OnStart()
--System:BindNotify(msgId,callback,ref)第一个参数是消息id,第二个参数是回调函数(这里传入了函数名),第三个参数是回调函数所属的self
System:BindNotify(NetMsg.OnSeverLog, self.OnSeverLog, self)
end
--步骤4:编辑收到消息后回调函数的逻辑,这里的例子是在客户端收到消息后打印log
function GameClient:OnSeverLog(msgId, msg)
--第一个参数是消息id,第二个参数是消息内容
if msg then
printLog("[GameClient:OnSeverLog]", msgId, table.unpack(msg))
end
end

备注:如果是服务器收到客户端消息,回调函数参数一般写成如下面的例子

function GameServer:OnMsgRequest(msgId, msg, playerId)
--第三个参数是发消息的客户端玩家角色id
printLog("Client Msg Request",msgId, msg.text, msg.count,playerId)
--试着日志打印各项参数
end

备注:如果不需要使用self(冒号代表函数默认传入了self参数),那么在注册时也可以省略self,例如下文:

System:BindNotify(_CS.NetNotify.OnSeverLog, OnSeverLog)

对应的回调函数可以这样写:

local function OnSeverLog(msgId, msg)

更多关于冒号参数的使用:

MyClass:FunWithParams(1,2,3,4)
--调用函数并传入四个参数,实际传入五个参数为self,1,2,3,4
MyClass.FunWithParams(1,2,3,4)
--调用函数并传入四个参数,实际传入四个参数为1,2,3,4
FunWithParams(1,2,3,4)
--(本地函数用法)调用函数并传入四个参数,实际传入四个参数为1,2,3,4
--总结:带冒号函数的会有一个隐藏self传出去,下面会有各种函数的写法和调用方法,参数传入按照顺序一一对应
function Myclass:FunWithParams(a,b,c)
--实际传参顺序为self,a,b,c,(有个隐藏的self)
--在各种情况下实际获取到的参数
--MyClass:FunWithParams(1,2,3,4) self = self a = 1 b = 2 c = 3 用冒号的话会多传一个self进来
--MyClass.FunWithParams(1,2,3,4) self = 1 a = 2 b = 3 c = 4
--FunWithParams(1,2,3,4) self = 1 a = 2 b = 3 c = 4
end
local function FunWithParams(a,b,c)
--实际传参顺序为a,b,c,(没有self,所以访问self的话是nil,也可以自己在参数那边写个self)
--在各种情况下实际获取到的参数
--FunWithParams(1,2,3,4) a = 1 b = 2 c = 3
end
function Myclass.FunWithParams(a,b,c)
--实际传参顺序为a,b,c,(没有self,所以访问self的话是nil,也可以自己在参数那边写个self)
--在各种情况下实际获取到的参数
--MyClass:FunWithParams(1,2,3,4) a = self b = 1 c = 2 用冒号的话会多传一个self进来
--MyClass.FunWithParams(1,2,3,4) a = 1 b = 2 c = 3
end
function(a,b,c)
--实际传参顺序为a,b,c,(没有self,所以访问self的话是nil,也可以自己在参数那边写个self)
--此为匿名函数
--在各种情况下实际获取到的参数
----------------------------------------------------------------------
System:SendToServer(_CS.NetNotify.OnFunWithParams,1,2,3)
System:BindNotify(_CS.NetNotify.OnFunWithParams, function(a,b,c)
a = 1,b=2,c=3
end)
System:SendToServer(_CS.NetNotify.OnFunWithParams,1,2,3)
System:BindNotify(_CS.NetNotify.OnFunWithParams, function(a,b,c)
a = self,b=1,c=2
--因为bind后面加了一个参数self,所以实际传参顺序为self,1,2,3
--这部分不要死记硬背 只是这个api会这样传
--注意看文档给个回调函数的参数数量,只要一一对应就没问题,本质上这个就是没冒号的普通函数
--不过是匿名无法被其他地方使用而已
--建议匿名函数只在回调函数中使用,免得混淆
end,self)
----------------------------------------------------------------------
end