skynet_笔记
skynet 相关笔记
skynet.register(“login”)
- 据说是历史遗留问题,不推荐使用
- 推荐使用
skynet.uniqueservice
- 参考:https://github.com/cloudwu/skynet/issues/169
切记事项
- 不能用 lua 自带的 print, 否则会崩溃。具体原因还没查
获取本服务名称
- SERVICE_NAME
修改 rpc 解析
登陆服
游戏服
消息重定向
例如调用在 gateserver.lua 中需要将客户端的消息 重定向 到 agent.lua ,可以调用这个api
1
skynet.redirect (agent, 0, "client", 0, msg, sz)
要使 msg 重定向到 agent 中,有两个前置条件
在 gateserver.lua 中注册一个 client 协议,例如这样就可以了
1
2
3
4skynet.register_protocol {
name = "client",
id = skynet.PTYPE_CLIENT,
}在 agent.lua 中同样需要一个注册一个 client 协议
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19skynet.register_protocol {
name = "client",
id = skynet.PTYPE_CLIENT,
unpack = function (msg, sz)
print("------ 终于来带这里解析了, msg:", type(msg))
return host:dispatch (msg, sz) -- 客户端使用的sproto,所以这里用sproto解码
end,
dispatch = function (source, session, type, ...)
print("------ 终于来带这里解析了 222, type:", type(type))
if type == "REQUEST" then
handle_request (...) -- 处理客户端的请求
elseif type == "RESPONSE" then
handle_response (...) -- 处理请求客户端后的响应(客户端返回)
else
syslog.warningf ("invalid message type : %s", type)
kick_self ()
end
end,
}
如果少了第一步,会报错:
1
2
3[:00000016] lua call [0 to :16 : 0 msgsz = 24] error : ../3rd/skynet/lualib/skynet.lua:534: ../3rd/skynet/lualib/skynet.lua:156: ../3rd/skynet/lualib/skynet.lua:377: attempt to index a nil value (field '?')
stack traceback:
../3rd/skynet/lualib/skynet.lua:377: in function 'skynet.redirect'
关于 gateserver.lua 中 msg 是 c 指针问题
如果需要接入自己的 rpc 协议解析,必然要使用的这个 msg,但是这里的 msg 是个 c 指针。官方提供了一个 api:
netpack.tostring
可以把这个 msg 转成 string 流,然后就可以按你自己的方式去处理这个消息1
2
3
4
5
6
7
8
9
10local netpack = require "skynet.netpack"
local function my_read_msg(fd, msg, sz)
local msg = netpack.tostring(msg, sz)
local proto_id, params = string.unpack(">Hs2", msg)
local proto_name = msg_define.id_2_name(proto_id)
local paramTab = Utils.str_2_table(params)
print("--- proto_name:", proto_name)
print("--- params:", params)
return proto_name, paramTab
end
关于 socket.lua 的使用
由于里面有注册 socket 协议, 所以不能在 自定义的服务中 再次注册 socket 协议
1
2
3
4
5
6
7
8skynet.register_protocol {
name = "socket",
id = skynet.PTYPE_SOCKET, -- PTYPE_SOCKET = 6
unpack = driver.unpack,
dispatch = function (_, _, t, ...)
socket_message[t](...)
end
}之前踩的坑:gateserver.lua 中有注册 socket 协议,但又想包读信息的分装到一个单独文件 proto_process.lua 中,里面有 require “skynet.socket” ,所以报错
1
2
3
4
5[:00000016] lua loader error : ../3rd/skynet/lualib/skynet.lua:39: -------------- exit name:socket
stack traceback:
[C]: in function 'assert'
../3rd/skynet/lualib/skynet.lua:39: in function 'skynet.register_protocol'
./lualib/gameserver/gateserver.lua:127: in function 'gameserver.gateserver.start'
游戏服登陆分析
断线重连
- 必然是先关闭 socket
挤号重登
- socket 还在时,需要发给客户端 “已在其他地方登陆的提示”,然后主动断掉socket,新 socket 分配 agent
定时器
时间间隔 3s,2s后执行
1
2
3
4
5local function timer( ... )
print("--- timer ", skynet.now())
skynet.timeout(300, timer)
end
skynet.timeout(200, timer)测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27function cancelable_timeout(ti, func)
local function cb()
if func then
func()
end
end
local function cancel()
func = nil
end
skynet.timeout(ti, cb)
return cancel
end
local cancel = nil
print("--- timer test")
local counter = 0
local function timer( ... )
counter = counter + 1
print("--- timer ", skynet.now())
if counter == 3 then
cancel()
else
skynet.timeout(200, timer)
end
end
-- skynet.timeout(0, timer)
cancel = cancelable_timeout(0, timer)