5e6af9d6
zhouhaihai
排队功能
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
-- 排队系统
require "ProtocolCode"
require "shared.init"
require "utils.init"
require "GlobalVar"
require "RedisKeys"
require "skynet.manager"
local queue = require "skynet.queue"
local netpack = require "skynet.netpack"
local socket = require "skynet.socket"
local xxtea = require "xxtea"
skynet = require "skynet"
local MAX_COUNT = tonumber(skynet.getenv("max_queue"))
-- 心跳定时间隔
local HEART_TIMER_INTERVAL = 30
local HEART_TIMEOUT_COUNT_MAX = 3
|
5e6af9d6
zhouhaihai
排队功能
|
21
22
23
24
25
26
27
28
29
|
local CMD = {}
local f2u = {}
local u2i = {} -- {idx, fd, {lastHeart, timeOutCount, nextCheck}}
local idx2u = {}
local curIdx = 0 -- 下一个即将进入游戏的玩家索引
local nextIdx = 0 -- 新加的位置
|
5e6af9d6
zhouhaihai
排队功能
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
local function getRank(uid)
local info = u2i[uid]
if not info then return -1 end
return (info[1] + MAX_COUNT - curIdx) % MAX_COUNT + 1
end
function SendPacket(actionCode, bin, client_fd)
if #bin > 0 then bin = xxtea.encrypt(bin, XXTEA_KEY) end
local head = string.pack("H", actionCode)
return socket.write(client_fd, netpack.pack(head .. bin))
end
local function checkQueue(fd)
if not f2u[fd] then return end
local info = u2i[f2u[fd]]
if info then
info[3][1] = skynet.timex()
end
local rank = getRank(f2u[fd])
SendPacket(actionCodes.Sys_checkQueue, MsgPack.pack({rank = rank}), fd)
end
skynet.register_protocol {
name = "client",
id = skynet.PTYPE_CLIENT,
unpack = function (msg, sz)
local data = skynet.tostring(msg, sz)
local cmd = string.unpack("H", string.sub(data, 1, 2))
return cmd, string.sub(data, 3)
end,
dispatch = function(session, address, cmd, data)
skynet.ignoreret()
|
e24d1abd
zhouhaihai
修改 排队
|
64
65
66
|
if cmd == actionCodes.Sys_checkQueue then
checkQueue(session)
end
|
5e6af9d6
zhouhaihai
排队功能
|
67
68
69
|
end
}
|
5e6af9d6
zhouhaihai
排队功能
|
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
function CMD.push(uid, fd)
uid = tostring(uid)
if u2i[uid] then -- 存在]
local oldfd = u2i[uid][2]
if oldfd and oldfd ~= fd then
-- 踢掉老的
SendPacket(actionCodes.Sys_maintainNotice, MsgPack.pack({body = "server_accountOccupied", iskey = true}), oldfd)
skynet.timeout(10, function ()
skynet.call(gate_serv, "lua", "kick", oldfd)
end)
f2u[oldfd] = nil
end
u2i[uid][2] = fd
f2u[fd] = uid
u2i[uid][3] = {skynet.timex(), 0, skynet.timex() + HEART_TIMER_INTERVAL}
else -- 新排队的用户
if nextIdx == curIdx and next(idx2u) then -- 满了
return
end
u2i[uid] = {nextIdx, fd, {skynet.timex(), 0, skynet.timex() + HEART_TIMER_INTERVAL}}
f2u[fd] = uid
idx2u[nextIdx] = uid
nextIdx = (nextIdx + 1) % MAX_COUNT
end
skynet.call(gate_serv, "lua", "forward", fd, 0, skynet.self())
return getRank(uid)
end
function CMD.pop()
while true do
local uid = idx2u[curIdx]
if not uid then return end -- 空的
local info = u2i[uid]
if not info then
idx2u[curIdx] = nil
else
if info[2] then
-- 找到合适的了
u2i[uid] = nil
idx2u[curIdx] = nil
f2u[info[2]] = nil
curIdx = (curIdx + 1) % MAX_COUNT
return uid, info[2]
else
idx2u[curIdx] = nil
u2i[uid] = nil
end
end
curIdx = (curIdx + 1) % MAX_COUNT
end
end
|
e24d1abd
zhouhaihai
修改 排队
|
124
|
|
5e6af9d6
zhouhaihai
排队功能
|
125
126
127
128
129
130
131
132
133
|
-- 下线了
function CMD.socket_close(fd)
local uid = f2u[fd]
if not uid then return end
f2u[fd] = nil
local info = u2i[uid]
info[2] = nil
end
|
e24d1abd
zhouhaihai
修改 排队
|
134
|
function CMD.handle_timeout()
|
5e6af9d6
zhouhaihai
排队功能
|
135
136
137
138
139
140
141
142
143
144
145
146
147
|
local now = skynet.timex()
for uid, info in pairs(u2i) do
if info[2] and info[3] and now >= info[3][3] then --存在fd 检查心跳
if info[3][1] - now > HEART_TIMER_INTERVAL or now - info[3][1] > HEART_TIMER_INTERVAL then
info[3][2] = info[3][2] + 1
info[3][3] = now + HEART_TIMER_INTERVAL
if info[3][2] >= HEART_TIMEOUT_COUNT_MAX then
skynet.error("timeout! then queued will closed", info[2], uid)
skynet.call(gate_serv, "lua", "kick", info[2])
end
end
end
end
|
5e6af9d6
zhouhaihai
排队功能
|
148
149
|
end
|
e24d1abd
zhouhaihai
修改 排队
|
150
151
152
|
function CMD.count()
return (nextIdx + MAX_COUNT - curIdx) % MAX_COUNT
end
|
5e6af9d6
zhouhaihai
排队功能
|
153
|
|
e24d1abd
zhouhaihai
修改 排队
|
154
|
return CMD
|