mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +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
|
||||
|
||||
local session = 0
|
||||
|
||||
local function send_request(v)
|
||||
session = session + 1
|
||||
local function send_request(v, session)
|
||||
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)
|
||||
return session, v
|
||||
return v, session
|
||||
end
|
||||
|
||||
local function recv_response(v)
|
||||
@@ -87,7 +84,7 @@ local function recv_response(v)
|
||||
local c = v:byte(i)
|
||||
session = session + bit32.lshift(c,(-1-i) * 8)
|
||||
end
|
||||
return ok ~=0 , session, content
|
||||
return ok ~=0 , content, session
|
||||
end
|
||||
|
||||
local input = {}
|
||||
@@ -115,32 +112,44 @@ local function readpackage()
|
||||
end
|
||||
end
|
||||
|
||||
local text = "echo"
|
||||
local index = 1
|
||||
|
||||
local function echo(text)
|
||||
print("connect")
|
||||
local fd = assert(socket.connect("127.0.0.1", 8888))
|
||||
input = {}
|
||||
print("connect")
|
||||
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)
|
||||
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))
|
||||
socket.send(fd, handshake .. ":" .. crypt.base64encode(hmac))
|
||||
|
||||
print(readpackage())
|
||||
print("===>",send_request(text))
|
||||
print("===>",send_request(text .. " again"))
|
||||
print("<===",recv_response(readpackage()))
|
||||
print("<===",recv_response(readpackage()))
|
||||
print(readpackage())
|
||||
print("===>",send_request(text,0))
|
||||
-- don't recv response
|
||||
-- print("<===",recv_response(readpackage()))
|
||||
|
||||
print("disconnect")
|
||||
socket.close(fd)
|
||||
end
|
||||
|
||||
echo "hello"
|
||||
print("disconnect")
|
||||
socket.close(fd)
|
||||
|
||||
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)
|
||||
-- the simple ehco service
|
||||
skynet.sleep(10) -- sleep a while
|
||||
skynet.ret(msg)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -212,18 +212,21 @@ function server.start(conf)
|
||||
|
||||
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)
|
||||
if u.index >= expired_number * 2 then
|
||||
local max = 0
|
||||
local response = u.response
|
||||
for k,p in pairs(response) do
|
||||
if p[3] < expired_number then
|
||||
response[k] = nil
|
||||
else
|
||||
p[3] = p[3] - expired_number
|
||||
if p[3] > max then
|
||||
max = p[3]
|
||||
if p[1] == nil then
|
||||
-- request complete, check expired
|
||||
if p[4] < expired_number then
|
||||
response[k] = nil
|
||||
else
|
||||
p[4] = p[4] - expired_number
|
||||
if p[4] > max then
|
||||
max = p[4]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -238,14 +241,23 @@ function server.start(conf)
|
||||
local p = u.response[session]
|
||||
if p then
|
||||
-- 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
|
||||
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
|
||||
|
||||
if p == nil then
|
||||
p = { fd }
|
||||
u.response[session] = p
|
||||
local ok, result = pcall(conf.request_handler, u.username, msg, msg_sz)
|
||||
result = result or ""
|
||||
-- NOTICE: YIELD here, socket may close.
|
||||
if not ok then
|
||||
skynet.error(result)
|
||||
@@ -254,21 +266,28 @@ function server.start(conf)
|
||||
result = result .. '\1' .. session
|
||||
end
|
||||
|
||||
p = { netpack.pack_string(result), u.version, u.index }
|
||||
if u.response[session] then
|
||||
skynet.error(string.format("Conflict session %s", crypt.hexencode(session)))
|
||||
end
|
||||
u.response[session] = p
|
||||
p[2] = netpack.pack_string(result)
|
||||
p[3] = u.version
|
||||
p[4] = u.index
|
||||
else
|
||||
netpack.tostring(msg, sz) -- request before, so free msg
|
||||
-- resend response, and update index p[3].
|
||||
p[3] = u.index
|
||||
-- update version/index, change return fd.
|
||||
-- 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
|
||||
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
|
||||
socketdriver.send(fd, p[1])
|
||||
socketdriver.send(fd, p[2])
|
||||
end
|
||||
p[1] = nil
|
||||
retire_response(u)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user