1、确认登录接口
在完成了登录流程后,login会通知gateway(第⑧阶段),让它把客户端连接和新agent(第⑨阶段)关联起来。
sure_agent代码如下所示:
s.resp.sure_agent = function(source, fd, playerid, agent)
local conn = conns[fd]
if not conn then --登陆过程中已经下线
skynet.call("agentmgr", "lua", "reqkick", playerid, "未完成登陆即下线")
return false
end
conn.playerid = playerid
local gplayer = gateplayer()
gplayer.playerid = playerid
gplayer.agent = agent
gplayer.conn = conn
players[playerid] = gplayer
return true
end
- 参数source:消息发送方;
- 参数fd:客户端连接标识;
- 参数playerid:已登录的角色(玩家)id;
- 参数agent:处理该角色的代理服务id,这些参数由调用方传递。
sure_agent的功能是将fd和playerid关联起来,它会先查找连接对象conn,再创建gateplayer对象gplayer,并设置属性。
2、登出流程
玩家有两种登出的情况,一种是客户端掉线,另一种是被顶替下线。若是客户端掉线,会调用如下所示的disconnect方法。
local disconnect = function(fd)
local c = conns[fd]
if not c then
return
end
local playerid = c.playerid
--还没完成登录
if not playerid then
return
--已在游戏中
else
players[playerid] = nil
local reason = "断线"
skynet.call("agentmgr", "lua", "reqkick", playerid, reason)
end
end
按照下图所示的登出流程,gateway会向agentmgr发送下线请求“reqkick”,由agentmgr仲裁。
如果agentmgr仲裁通过,或是agentmgr想直接把玩家踢下线,在保存数据后,它会通知gateway,来删掉玩家对应的conn和gateplayer对象。
s.resp.kick = function(source, playerid)
local gplayer = players[playerid]
if not gplayer then
return
end
local c = gplayer.conn
players[playerid] = nil
if not c then
return
end
conns[c.fd] = nil
disconnect(c.fd)
socket.close(c.fd)
end
3、gateway测试
代码写到这里,我们的gateway网关这一块的功能差不多就基本写完了。写完之后,我们可以进行一个简单的测试,用telnet客户端测试gateway能否正常工作。
(1)输入指令开启主服务:
(2)使用telnet客户端连接主服务:
(3)输入消息,由于在telnet换行即为输入分隔符“\r\n”,因此直接用换行分割消息即可:
完整代码地址:https://gitee.com/frank-yangyu/ball-server/tree/master