简单的说就是:
1.先连接登录服务器进行验证
2.登录验证成功后连接游戏服务器,后面就是游戏包的流程了
先说luasocket的连接
-- 设置ipv6
local isipv6_only = false
local addrinfo, err = socket.dns.getaddrinfo(self.host)
for i,v in ipairs(addrinfo) do
if v.family == "inet6" then
isipv6_only = true;
break
end
end
if isipv6_only then
self.tcp = socket.tcp6()
else
self.tcp = socket.tcp()
end
self.tcp:settimeout(0)
创建tcp
function SocketTCP:_connect()
local __succ, __status = self.tcp:connect(self.host, self.port)
return __succ == 1 or __status == STATUS_ALREADY_CONNECTED
end
然后是连接ip和端口,status返回status_already_connected表示连接成功,_connetct放在tick里面检测是否连接成功,设定连接时间,到时间返回错误
local __tick = function()
while true do
local __body, __status, __partial = self.tcp:receive("*a") -- read the package body
if __status == STATUS_CLOSED or __status == STATUS_NOT_CONNECTED then
self:close()
if self.isConnected then
self:_onDisconnect()
else
self:_connectFailure()
end
return
end
if (__body and string.len(__body) == 0) or (__partial and string.len(__partial) == 0) then return end
if __body and __partial then
__body = __body .. __partial
end
self:dispatchEvent({name=SocketTCP.EVENT_DATA, data=(__partial or __body), partial=__partial, body=__body})
end
end
连接成功后就是用tcp:receive("*a")读取接收数据处理,同样是在tick里直到连接失败
前面提到过连接登录服务器和游戏服务器都是要通以上sockettcp来连接
现在说下登录服务器验证, 以skynet为例,调用connect连接成功后收到服务器数据进行认证,如下
self._dispatch = function(self, msg)
local state = self.__state
if state == 1 then
S_EXCHANGE_KEY(msg)
self.__state = 2
elseif state == 2 then
S_SCERET(msg)
self.__state = 10
elseif state == 10 then --检测版本
S_CHECK_VERSION(msg)
self.__state = 3
elseif state == 3 then
if not S_AUTH_BEGIN(msg) then
self.__state = 6
end
self.__state = 4
elseif state == 4 then
if not S_AUTH(msg) then
self.__state = 6
return
end
self.__state = 5
closefd(self)
--设置新的处理函数
self.connect = connect_gameserver
self.reconnect = reconnect_gameserver
self.request = request_gameserver
self.close = closefd
return cb(self)
end
end
在state=5的时候已经验证成功,关闭与登录服务器的连接,开始与游戏服务器连接,连接返回成功后前端立即发送secret(验证时获取)给游戏服务器进行验证,验证成功后进入游戏正常发包流程