> 文章列表 > 【从零开始学Skynet】实战篇《球球大作战》(七):gateway代码设计(下)

【从零开始学Skynet】实战篇《球球大作战》(七):gateway代码设计(下)

【从零开始学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的功能是将fdplayerid关联起来,它会先查找连接对象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,来删掉玩家对应的conngateplayer对象。

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