mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
bugfix: update the response fd, when the client reconnect
This commit is contained in:
@@ -70,13 +70,10 @@ print("login ok, subid=", subid)
|
|||||||
|
|
||||||
----- connect to game server
|
----- connect to game server
|
||||||
|
|
||||||
local session = 0
|
local function send_request(v, session)
|
||||||
|
|
||||||
local function send_request(v)
|
|
||||||
session = session + 1
|
|
||||||
local s = string.char(bit32.extract(session,24,8), bit32.extract(session,16,8), bit32.extract(session,8,8), bit32.extract(session,0,8))
|
local s = string.char(bit32.extract(session,24,8), bit32.extract(session,16,8), bit32.extract(session,8,8), bit32.extract(session,0,8))
|
||||||
socket.send(fd , v..s)
|
socket.send(fd , v..s)
|
||||||
return session, v
|
return v, session
|
||||||
end
|
end
|
||||||
|
|
||||||
local function recv_response(v)
|
local function recv_response(v)
|
||||||
@@ -87,7 +84,7 @@ local function recv_response(v)
|
|||||||
local c = v:byte(i)
|
local c = v:byte(i)
|
||||||
session = session + bit32.lshift(c,(-1-i) * 8)
|
session = session + bit32.lshift(c,(-1-i) * 8)
|
||||||
end
|
end
|
||||||
return ok ~=0 , session, content
|
return ok ~=0 , content, session
|
||||||
end
|
end
|
||||||
|
|
||||||
local input = {}
|
local input = {}
|
||||||
@@ -115,32 +112,44 @@ local function readpackage()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local text = "echo"
|
||||||
local index = 1
|
local index = 1
|
||||||
|
|
||||||
local function echo(text)
|
print("connect")
|
||||||
print("connect")
|
local fd = assert(socket.connect("127.0.0.1", 8888))
|
||||||
local fd = assert(socket.connect("127.0.0.1", 8888))
|
input = {}
|
||||||
input = {}
|
|
||||||
|
|
||||||
local handshake = string.format("%s@%s#%s:%d", crypt.base64encode(token.user), crypt.base64encode(token.server),crypt.base64encode(subid) , index)
|
local handshake = string.format("%s@%s#%s:%d", crypt.base64encode(token.user), crypt.base64encode(token.server),crypt.base64encode(subid) , index)
|
||||||
local hmac = crypt.hmac64(crypt.hashkey(handshake), secret)
|
local hmac = crypt.hmac64(crypt.hashkey(handshake), secret)
|
||||||
|
|
||||||
socket.send(fd, handshake .. ":" .. crypt.base64encode(hmac))
|
socket.send(fd, handshake .. ":" .. crypt.base64encode(hmac))
|
||||||
|
|
||||||
print(readpackage())
|
print(readpackage())
|
||||||
print("===>",send_request(text))
|
print("===>",send_request(text,0))
|
||||||
print("===>",send_request(text .. " again"))
|
-- don't recv response
|
||||||
print("<===",recv_response(readpackage()))
|
-- print("<===",recv_response(readpackage()))
|
||||||
print("<===",recv_response(readpackage()))
|
|
||||||
|
|
||||||
print("disconnect")
|
print("disconnect")
|
||||||
socket.close(fd)
|
socket.close(fd)
|
||||||
end
|
|
||||||
|
|
||||||
echo "hello"
|
|
||||||
|
|
||||||
index = index + 1
|
index = index + 1
|
||||||
|
|
||||||
echo "world"
|
print("connect again")
|
||||||
|
local fd = assert(socket.connect("127.0.0.1", 8888))
|
||||||
|
input = {}
|
||||||
|
|
||||||
|
local handshake = string.format("%s@%s#%s:%d", crypt.base64encode(token.user), crypt.base64encode(token.server),crypt.base64encode(subid) , index)
|
||||||
|
local hmac = crypt.hmac64(crypt.hashkey(handshake), secret)
|
||||||
|
|
||||||
|
socket.send(fd, handshake .. ":" .. crypt.base64encode(hmac))
|
||||||
|
|
||||||
|
print(readpackage())
|
||||||
|
print("===>",send_request("fake",0)) -- request again (use last session 0, so the request message is fake)
|
||||||
|
print("===>",send_request("again",1)) -- request again (use new session)
|
||||||
|
print("<===",recv_response(readpackage()))
|
||||||
|
print("<===",recv_response(readpackage()))
|
||||||
|
|
||||||
|
|
||||||
|
print("disconnect")
|
||||||
|
socket.close(fd)
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ skynet.start(function()
|
|||||||
|
|
||||||
skynet.dispatch("client", function(_,_, msg)
|
skynet.dispatch("client", function(_,_, msg)
|
||||||
-- the simple ehco service
|
-- the simple ehco service
|
||||||
|
skynet.sleep(10) -- sleep a while
|
||||||
skynet.ret(msg)
|
skynet.ret(msg)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@@ -212,18 +212,21 @@ function server.start(conf)
|
|||||||
|
|
||||||
local request_handler = assert(conf.request_handler)
|
local request_handler = assert(conf.request_handler)
|
||||||
|
|
||||||
-- u.response is a struct { message, version, index }
|
-- u.response is a struct { return_fd , response, version, index }
|
||||||
local function retire_response(u)
|
local function retire_response(u)
|
||||||
if u.index >= expired_number * 2 then
|
if u.index >= expired_number * 2 then
|
||||||
local max = 0
|
local max = 0
|
||||||
local response = u.response
|
local response = u.response
|
||||||
for k,p in pairs(response) do
|
for k,p in pairs(response) do
|
||||||
if p[3] < expired_number then
|
if p[1] == nil then
|
||||||
response[k] = nil
|
-- request complete, check expired
|
||||||
else
|
if p[4] < expired_number then
|
||||||
p[3] = p[3] - expired_number
|
response[k] = nil
|
||||||
if p[3] > max then
|
else
|
||||||
max = p[3]
|
p[4] = p[4] - expired_number
|
||||||
|
if p[4] > max then
|
||||||
|
max = p[4]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -238,14 +241,23 @@ function server.start(conf)
|
|||||||
local p = u.response[session]
|
local p = u.response[session]
|
||||||
if p then
|
if p then
|
||||||
-- session can be reuse in the same connection
|
-- session can be reuse in the same connection
|
||||||
if p[2] == u.version then
|
if p[3] == u.version then
|
||||||
|
local last = u.response[session]
|
||||||
u.response[session] = nil
|
u.response[session] = nil
|
||||||
p = nil
|
p = nil
|
||||||
|
if last[2] == nil then
|
||||||
|
local error_msg = string.format("Conflict session %s", crypt.hexencode(session))
|
||||||
|
skynet.error(error_msg)
|
||||||
|
error(error_msg)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if p == nil then
|
if p == nil then
|
||||||
|
p = { fd }
|
||||||
|
u.response[session] = p
|
||||||
local ok, result = pcall(conf.request_handler, u.username, msg, msg_sz)
|
local ok, result = pcall(conf.request_handler, u.username, msg, msg_sz)
|
||||||
|
result = result or ""
|
||||||
-- NOTICE: YIELD here, socket may close.
|
-- NOTICE: YIELD here, socket may close.
|
||||||
if not ok then
|
if not ok then
|
||||||
skynet.error(result)
|
skynet.error(result)
|
||||||
@@ -254,21 +266,28 @@ function server.start(conf)
|
|||||||
result = result .. '\1' .. session
|
result = result .. '\1' .. session
|
||||||
end
|
end
|
||||||
|
|
||||||
p = { netpack.pack_string(result), u.version, u.index }
|
p[2] = netpack.pack_string(result)
|
||||||
if u.response[session] then
|
p[3] = u.version
|
||||||
skynet.error(string.format("Conflict session %s", crypt.hexencode(session)))
|
p[4] = u.index
|
||||||
end
|
|
||||||
u.response[session] = p
|
|
||||||
else
|
else
|
||||||
netpack.tostring(msg, sz) -- request before, so free msg
|
netpack.tostring(msg, sz) -- request before, so free msg
|
||||||
-- resend response, and update index p[3].
|
-- update version/index, change return fd.
|
||||||
p[3] = u.index
|
-- resend response.
|
||||||
|
p[1] = fd
|
||||||
|
p[3] = u.version
|
||||||
|
p[4] = u.index
|
||||||
|
if p[2] == nil then
|
||||||
|
-- already request, but response is not ready
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
u.index = u.index + 1
|
u.index = u.index + 1
|
||||||
-- check connect again
|
-- the return fd is p[1] (fd may change by multi request) check connect
|
||||||
|
fd = p[1]
|
||||||
if connection[fd] then
|
if connection[fd] then
|
||||||
socketdriver.send(fd, p[1])
|
socketdriver.send(fd, p[2])
|
||||||
end
|
end
|
||||||
|
p[1] = nil
|
||||||
retire_response(u)
|
retire_response(u)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user