【从零开始学Skynet】实战篇《球球大作战》(七):gateway代码设计(下)
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 falseendconn.playerid = playeridlocal gplayer = gateplayer()gplayer.playerid = playeridgplayer.agent = agentgplayer.conn = connplayers[playerid] = gplayerreturn 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 thenreturnendlocal playerid = c.playerid--还没完成登录if not playerid thenreturn--已在游戏中elseplayers[playerid] = nillocal 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 thenreturnendlocal c = gplayer.connplayers[playerid] = nilif not c thenreturnendconns[c.fd] = nildisconnect(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