Skip to content
This repository has been archived by the owner on Dec 30, 2023. It is now read-only.

Commit

Permalink
msgserver support server push instead of long poll
Browse files Browse the repository at this point in the history
  • Loading branch information
fztcjjl committed Dec 11, 2015
1 parent ceea11f commit 386ee02
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 89 deletions.
4 changes: 2 additions & 2 deletions game/gated.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ function server.init_handler()
end

-- 与游服握手成功后回调
function server.auth_handler(username)
function server.auth_handler(username, fd)
local uid = msgserver.userid(username)
uid = tonumber(uid)

LOG_INFO("notify agent uid=%d is real login", uid)
skynet.call(users[uid].agent, "lua", "auth", uid) -- 通知agent认证成功,玩家真正处于登录状态了
skynet.call(users[uid].agent, "lua", "auth", uid, fd) -- 通知agent认证成功,玩家真正处于登录状态了
end

-- login server disallow multi login, so login_handler never be reentry
Expand Down
8 changes: 6 additions & 2 deletions game/msgagent.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ local cs = queue()
local UID
local SUB_ID
local SECRET

local fd
--local user_dc
local afktime = 0

Expand Down Expand Up @@ -132,7 +134,8 @@ function CMD.login(source, uid, subid, secret)
end

-- 玩家登录游服,握手成功后调用
function CMD.auth(source, uid)
function CMD.auth(source, uid, client_fd)
fd = client_fd
LOG_INFO(string.format("%d is real login", uid))
LOG_INFO("call dcmgr to load user data uid=%d", uid)
skynet.call("dcmgr", "lua", "load", uid) -- 加载玩家数据,重复加载是无害的
Expand Down Expand Up @@ -217,7 +220,8 @@ local function msg_dispatch(netmsg)
obj.req[method], {
name = name,
payload = netmsg.payload,
uid = uid
uid = uid,
fd = fd
}
)

Expand Down
7 changes: 6 additions & 1 deletion game/user/role.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ function response.roleinit(uid, name)
}

local ret = user_dc.req.add(data)

if ret then
local userinfo = user_dc.req.get(args.uid)
local name, resp = pb_encode("user.UserInfoResponse", userinfo)
end

-- 初始化角色其他数据

if not ret then
return ErrorCode.E_DB_ERROR
errno = ErrorCode.E_DB_ERROR
end
return errno
end
Expand Down
91 changes: 82 additions & 9 deletions game/user/user.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,104 @@ end

function response.load(uid)
if not uid then return end
EntUser:Load(uid)
EntUser:load(uid)
end

function response.unload(uid)
if not uid then return end
EntUser:UnLoad(uid)
EntUser:unload(uid)
end

function response.RoleInitRequest(data)
local args = pb_decode(data)
local errno = role_obj.req.roleinit(args.uid, args.name)
local name, resp = pb_encode("user.RoleInitResonpse", {})
return name, resp, errno
local uid = data.uid
local fd = data.fd
if user_dc.req.check_role_exists(uid) then
LOG_ERROR("uid %d has role, role init failed", uid)
return
end

local row = {
uid = uid,
name = args.name,
level = 1,
exp = 0,
rtime = os.time(),
ltime = os.time()
}

local ret = user_dc.req.add(row)

if ret then
local userinfo = user_dc.req.get(uid)
local name, resp = pb_encode("user.UserInfoResponse", userinfo)

local function format_errmsg(errno, errmsg)
local err = {}
err.code = errno or 0
err.desc = errmsg
return err
end
local x = {}
x.name = name
x.payload = resp
data.errmsg = format_errmsg(0)

send_client(data.fd, x)
end
end

function response.RoleRenameRequest(data)
local args = pb_decode(data)
local errno = role_obj.req.rolerename(args.uid, args.name)
local name, resp = pb_encode("user.RoleRenameResponse", {})
return name, resp, errno
local uid = data.uid
local fd = data.fd

if not user_dc.req.check_role_exists(uid) then
LOG_ERROR("uid %d has not a role, role rename failed", uid)
return
end

local ret = user_dc.req.setvalue(uid, "name", args.name)

if not ret then
return
end

local userinfo = user_dc.req.get(uid)
local name, resp = pb_encode("user.UserInfoResponse", userinfo)

local function format_errmsg(errno, errmsg)
local err = {}
err.code = errno or 0
err.desc = errmsg
return err
end
local x = {}
x.name = name
x.payload = resp
data.errmsg = format_errmsg(0)

send_client(data.fd, x)
end

function response.UserInfoRequest(data)
local args = pb_decode(data)
local userinfo = user_dc.req.get(args.uid)
print(userinfo)
local name, resp = pb_encode("user.UserInfoResponse", userinfo)
return name, resp

local function format_errmsg(errno, errmsg)
local err = {}
err.code = errno or 0
err.desc = errmsg
return err
end

local x = {}
x.name = name
x.payload = resp
data.errmsg = format_errmsg(0)

send_client(data.fd, x)
-- return name, resp
end
13 changes: 13 additions & 0 deletions global/util.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local skynet = require "skynet"
local protobuf = require "protobuf"
local socketdriver = require "socketdriver"

function do_redis(args, uid)
local cmd = assert(args[1])
Expand Down Expand Up @@ -79,3 +80,15 @@ end
function check_user_online(uid)
return skynet.call("gated", "lua", "is_online", uid)
end

function send_client(fd, data)
protobuf.register_file("./protocol/netmsg.pb")
local msg = protobuf.encode("netmsg.NetMsg", data)
if not msg then
LOG_ERROR("protobuf.encode error")
error("protobuf.encode error")
end
msg = msg .. string.pack(">BI4", 1, 888)
msg = string.pack(">s2", msg)
socketdriver.send(fd, msg)
end
78 changes: 3 additions & 75 deletions lualib/snax/msg_server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ function server.start(conf)
u.ip = addr
connection[fd] = u

auth_handler(username)
auth_handler(username, fd)
end

local function auth(fd, addr, msg, sz)
Expand All @@ -225,84 +225,12 @@ function server.start(conf)
end

local request_handler = assert(conf.request_handler)

-- 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[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
u.index = max + 1
end
end


local function do_request(fd, message)
local u = assert(connection[fd], "invalid fd")
local session = string.unpack(">I4", message, -4)
message = message:sub(1,-5)
local p = u.response[session]
if p then
-- session can be reuse in the same connection
if p[3] == u.version then -- 同一连接的请求,复用了先前的session
local last = u.response[session] -- 上一次该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, message)
-- NOTICE: YIELD here, socket may close.
result = result or ""
if not ok then
skynet.error(result)
result = string.pack(">BI4", 0, session)
else
result = result .. string.pack(">BI4", 1, session)
end

p[2] = string.pack(">s2",result)
p[3] = u.version
p[4] = u.index
else
-- 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
-- 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[2]) -- 发送应答包
end
p[1] = nil
retire_response(u)
pcall(conf.request_handler, u.username, message)
end

local function request(fd, msg, sz)
Expand Down

0 comments on commit 386ee02

Please sign in to comment.