现在开发登录流程涉及的最后一个服务agent,完成后就可以真正地把框架运行起来了。还会演示agent的单机功能,做个“打工”小游戏。
1、消息分发
玩家登录后,gateway会将客户端协议转发给agent(流程图的阶段⑨)。
新建service/agent/init.lua文件,代码如下所示:
s.resp.client = function(source, cmd, msg)
s.gate = source
if s.client[cmd] then
local ret_msg = s.client[cmd]( msg, source)
if ret_msg then
skynet.send(source, "lua", "send", s.id, ret_msg)
end
else
skynet.error("s.resp.client fail", cmd)
end
end
登录后客户端发送“work”协议,s.client.work方法将被调用。
代码中的变量含义如下:
- s.id:即玩家id;
- s.gate:新建一个变量用于保存玩家对应gateway的id。
2、数据加载
每个agent对应一个游戏角色,创建服务后,它要加载完所有角色数据才算完成职责。
定义如下所示的初始化方法:
s.init = function( )
--playerid = s.id
--在此处加载角色数据
skynet.sleep(200)
s.data = {
coin = 100,
hp = 200,
}
end
service模块将在服务启动时调用它。为了减少代码量,此处我们用阻塞2秒代替数据库读取数据的过程,大家可以参照基础篇中数据库操作相关知识,从数据库拉取玩家数据。读取出的数据保存在s.data中,它包含coin(金币)和hp(生命值)。
3、保存和退出
定义了kick和exit的远程调用,代码如下所示:
s.resp.kick = function(source)
s.leave_scene()
--在此处保存角色数据
skynet.sleep(200)
end
s.resp.exit = function(source)
skynet.exit()
end
为了减少代码量,此处用阻塞2秒代替s.resp.kick的保存过程,大家可以参照基础篇中数据库操作的知识实现数据库存储。s.resp.exit仅是对skynet.exit的简单封装,它用于实现退出服务的功
能。
4、单机测试
现在定义一个测试协议work,协议参数如下图所示。通过此协议实现让角色“打工”,然后获得金币。
work协议的处理方法如下代码所示:
s.client.work = function(msg)
s.data.coin = s.data.coin + 1
return {"work", s.data.coin}
end
它很简单,将coin的值加1,并返回带有最新金币数量的work协议,work协议会经由gateway发送给客户端。
完整代码下载地址:https://gitee.com/frank-yangyu/ball-server