314bc5df
zhengshouren
提交服务器初始代码
|
1
2
3
4
5
6
7
|
local skynet = require "skynet"
local socket = require "skynet.socket"
local redisproxy = require "shared.redisproxy"
local netpack = require "skynet.netpack"
local xxtea = require "xxtea"
local deque = require "deque"
local datacenter = require "skynet.datacenter"
|
e24d1abd
zhouhaihai
修改 排队
|
8
|
local agent_queued = require "services.agent_queued"
|
3f604f2e
zhouhaihai
扩容 redis 和 log服务
|
9
|
local logproxy = require "shared.logproxy"
|
314bc5df
zhengshouren
提交服务器初始代码
|
10
11
12
13
14
15
|
local pcall = pcall
local string_format = string.format
local poold
|
56484297
zhouhaihai
冒险消息
|
16
|
-- agent过期时间 5分钟
|
314bc5df
zhengshouren
提交服务器初始代码
|
17
18
19
20
21
22
23
24
25
26
27
28
29
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
|
local AGENT_EXPIRE_TIME = 300
local _M = {
-- fd -> uid
f2u = {},
-- uid -> 32 << fd | agent
u2f = {},
-- fd -> ip
f2i = {},
-- fd -> expire
f2e = {},
online = 0,
}
local function get_f(pack)
return (pack >> 32) & 0x7fffffff
end
local function get_a(pack)
return pack & 0xffffffff
end
local function set_pack(fd, agent)
return (fd << 32) | agent
end
function _M:init(obj, serice)
self.factory = deque.clone(obj)
poold = serice
end
-- @desc: agent退出
function _M:exit_agent(fd)
self.f2e[fd] = nil
local uid = self.f2u[fd]
if not uid then return end
local pack = self.u2f[uid]
if not pack then
self.f2u[fd] = nil
return
end
local agent = get_a(pack)
pcall(skynet.send, agent, "lua", "exit")
|
5e6af9d6
zhouhaihai
排队功能
|
63
|
|
e24d1abd
zhouhaihai
修改 排队
|
64
65
66
|
self.f2u[fd] = nil
self.u2f[uid] = nil
local nuid, nfd = agent_queued.pop()
|
5e6af9d6
zhouhaihai
排队功能
|
67
68
69
70
71
|
if not nuid then
pcall(skynet.send, poold, "lua", "feed")
else
self:query_agent(nfd, nuid, true)
end
|
314bc5df
zhengshouren
提交服务器初始代码
|
72
73
74
75
76
77
78
79
80
81
82
|
end
-- @desc: 客户端连入
function _M:socket_open(fd, addr)
self.f2i[fd] = addr
end
-- @desc: 网络关闭
function _M:socket_close(fd)
self.f2i[fd] = nil
local uid = self.f2u[fd]
|
5e6af9d6
zhouhaihai
排队功能
|
83
84
|
if not uid then
-- 排队中?
|
e24d1abd
zhouhaihai
修改 排队
|
85
|
agent_queued.socket_close(fd)
|
5e6af9d6
zhouhaihai
排队功能
|
86
87
|
return
end
|
314bc5df
zhengshouren
提交服务器初始代码
|
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
self.f2e[fd] = skynet.timex() + AGENT_EXPIRE_TIME
if not self.u2f[uid] then
self.f2u[fd] = nil
return
end
local agent = get_a(self.u2f[uid])
local ok, _ = pcall(skynet.call, agent, "lua", "close")
if not ok then self:exit_agent(fd) end
end
-- @desc: 网络出错
function _M:socket_error(fd)
self.f2i[fd] = nil
local uid = self.f2u[fd]
|
5e6af9d6
zhouhaihai
排队功能
|
103
104
|
if not uid then
-- 排队中?
|
e24d1abd
zhouhaihai
修改 排队
|
105
|
agent_queued.socket_close(fd)
|
5e6af9d6
zhouhaihai
排队功能
|
106
107
|
return
end
|
314bc5df
zhengshouren
提交服务器初始代码
|
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
if not self.u2f[uid] then
self.f2u[fd] = nil
return
end
local agent = get_a(self.u2f[uid])
-- 无论失败否,应该让逻辑走下去,保证agent状态以及索引正确
pcall(skynet.call, agent, "lua", "close")
self:exit_agent(fd)
end
local function table_nums(t)
local count = 0
for k, v in pairs(t) do
count = count + 1
end
return count
end
local next_check_time = 0
local next_log_time = 0
local CHECK_AGENT_STATUS_INTERVAL = 100 -- 检查agent状态的定时间隔
-- @desc: 检查agent状态,若过期,则让agent退出;并定时打日志统计在线人数
function _M:check_agent_status()
|
e24d1abd
zhouhaihai
修改 排队
|
132
|
agent_queued.handle_timeout()
|
314bc5df
zhengshouren
提交服务器初始代码
|
133
134
135
136
137
138
139
140
141
142
|
local now = skynet.timex()
if now >= next_check_time then
next_check_time = now + CHECK_AGENT_STATUS_INTERVAL
for fd, expire in pairs(self.f2e) do
if expire < now then
self:exit_agent(fd)
end
end
end
|
3f604f2e
zhouhaihai
扩容 redis 和 log服务
|
143
|
if now >= next_log_time and now % 60 == 0 then
|
314bc5df
zhengshouren
提交服务器初始代码
|
144
145
146
|
next_log_time = now + 60
local count = table_nums(self.u2f)
datacenter.set("onlineCount", count)
|
3f604f2e
zhouhaihai
扩容 redis 和 log服务
|
147
|
logproxy:log({["@type"] = "online", count = count}, "log")
|
314bc5df
zhengshouren
提交服务器初始代码
|
148
149
150
|
end
end
|
5e5d7680
zhouhaihai
热更新 优化
|
151
152
|
local hotfixList = {}
|
3fe4471e
zhouhaihai
热更新 demo
|
153
|
function _M:hotfix(code)
|
5e5d7680
zhouhaihai
热更新 优化
|
154
|
table.insert(hotfixList, code)
|
3fe4471e
zhouhaihai
热更新 demo
|
155
156
157
158
159
160
|
for uid, pack in pairs(self.u2f) do
local agent = get_a(pack)
pcall(skynet.send, agent, "lua", "hotfix", code)
end
end
|
314bc5df
zhengshouren
提交服务器初始代码
|
161
162
163
164
165
166
167
168
169
|
local function query_agent_response(fd, response)
local head = string.pack("H", actionCodes.Role_queryLoginRpc + rpcResponseBegin)
local bin = MsgPack.pack(response)
if #bin > 0 then bin = xxtea.encrypt(bin, XXTEA_KEY) end
socket.write(fd, netpack.pack(head .. bin))
end
-- @desc: 玩家登陆第一个包,queryLogin,watchdog为客户端分配一个agent,并告诉gate分配成功,之后的消息直接走agent
|
5e6af9d6
zhouhaihai
排队功能
|
170
|
function _M:query_agent(fd, uid, isQueue)
|
314bc5df
zhengshouren
提交服务器初始代码
|
171
172
173
174
175
176
177
|
local pack = self.u2f[uid]
if pack then
local f = get_f(pack)
if fd == f then
skynet.error(string.format("%s same fd %d", uid, fd))
return
end
|
314bc5df
zhengshouren
提交服务器初始代码
|
178
179
|
-- self.f2u[f] 肯定存在;self.f2e[f]不存在,则说明在线,则需要踢下线
if not self.f2e[f] then
|
2ee779d1
zhouhaihai
已经登陆
|
180
181
|
local head = string.pack("H", actionCodes.Sys_maintainNotice)
local bin = MsgPack.pack({body = "server_accountOccupied", iskey = true})
|
314bc5df
zhengshouren
提交服务器初始代码
|
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
if #bin > 0 then bin = xxtea.encrypt(bin, XXTEA_KEY) end
socket.write(f, netpack.pack(head .. bin))
skynet.timeout(10, function ()
skynet.call(gate_serv, "lua", "kick", f)
end)
end
local agent = get_a(pack)
local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd])
if not ok then
query_agent_response(fd, {ret = "INNER_ERROR"})
return
end
self.f2e[f] = nil
self.f2u[f] = nil
self.u2f[uid] = set_pack(fd, agent)
else
|
e24d1abd
zhouhaihai
修改 排队
|
200
|
local agent
|
5e6af9d6
zhouhaihai
排队功能
|
201
|
if isQueue then
|
e24d1abd
zhouhaihai
修改 排队
|
202
203
204
205
206
207
|
agent = self.factory:pop()
if agent then
pcall(skynet.send, poold, "lua", "feed")
else
agent = skynet.newservice("agent")
end
|
5e6af9d6
zhouhaihai
排队功能
|
208
|
else
|
e24d1abd
zhouhaihai
修改 排队
|
209
210
211
212
213
214
215
216
|
-- 该uid未存储,则说明至少超过10分钟未登陆,由agent池服务pop出一个agent
if agent_queued.count() > 0 then
-- 服务器满 开始排队
local rank = agent_queued.push(uid, fd)
query_agent_response(fd, {ret = "RET_SERVER_FULL", rank = rank})
return
end
|
5e6af9d6
zhouhaihai
排队功能
|
217
218
|
agent = self.factory:pop()
if not agent then
|
e24d1abd
zhouhaihai
修改 排队
|
219
|
local rank = agent_queued.push(uid, fd)
|
5e6af9d6
zhouhaihai
排队功能
|
220
221
222
|
query_agent_response(fd, {ret = "RET_SERVER_FULL", rank = rank})
return
end
|
314bc5df
zhengshouren
提交服务器初始代码
|
223
224
|
end
|
5e5d7680
zhouhaihai
热更新 优化
|
225
|
local ok = pcall(skynet.call, agent, "lua", "start", gate_serv, fd, self.f2i[fd], hotfixList)
|
314bc5df
zhengshouren
提交服务器初始代码
|
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
|
if not ok then
self.factory:push(agent)
query_agent_response(fd, {ret = "INNER_ERROR"})
return
end
self.u2f[uid] = set_pack(fd, agent)
end
self.f2u[fd] = uid
local response = {}
local user = redisproxy:get(string_format("uid:%s", uid))
if user then
response.ret = "RET_HAS_EXISTED"
response.name = user
else
response.ret = "RET_NOT_EXIST"
end
query_agent_response(fd, response)
end
return _M
|