314bc5df
zhengshouren
提交服务器初始代码
|
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
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
63
64
65
66
67
68
69
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
|
function skynet.launch(...)
c.command("LAUNCH", table.concat({...}, " "))
......
end
lua-skynet.c | _command | skynet_command
skynet_server.c | cmd_launch | skynet_context_new
====================================================================
function skynet.newservice(name, ...)
return skynet.call(".launcher", "lua" , "LAUNCH", "snlua", name, ...)
end
service/launcher.lua
返回 "RESPONSE", skynet.pack
newservice 收到 "RESPONSE"
launch 服务就有所有服务的地址
可以统计所有服务,gc某个服务,stats某个服务
====================================================================
再来看 skynet_context_new
1. 获取 skynet_module
struct skynet_module {
const char * name; 模块名
void * module; 模块对应的动态库(snlua, 或者其他动态库)
skynet_dl_create create; 创建函数
skynet_dl_init init; 初始化函数
skynet_dl_release release; 释放函数
skynet_dl_signal signal; 信号函数
};
2. 调用 M->create() 函数
创建 lua vm
struct snlua {
lua_State * L;
struct skynet_context * ctx;
};
构建 snlua 结构
3. 创建并初始化 上下文
struct skynet_context {
void * instance; snlua结构
struct skynet_module * mod;
void * cb_ud;
skynet_cb cb; callback函数指针
struct message_queue *queue; 消息队列
FILE * logfile; 日志输出文件
char result[32];
uint32_t handle;
int session_id;
int ref;
bool init;
bool endless;
CHECKCALLING_DECL
};
创建消息队列
4. 调用 M->init()函数
设置回调函数
skynet_callback(ctx, l , _launch);
ctx->cb 回调函数 _launch
ctx->cb_ud snlua结构
"REG" 注册
发送第一个消息
skynet_send(ctx, 0, handle_id, PTYPE_TAG_DONTCOPY, 0, tmp, sz);
调用 _launch 函数
skynet_callback(context, NULL, NULL);
将回调函数清空
接着调用 _init 函数
将 skynet_context 的指针地址 存入 lua 环境中 (通过轻量用户数据来实现)
加载常用库
将 LUA_PATH LUA_CPATH LUA_SERVICE LUA_PRELOAD 写入全局table中
通过 loader.lua 加载所有的lua库
5. 将次级消息队列压入全局消息队列
skynet_globalmq_push
6. 在服务主模块中调用
skynet.start 设置回调函数
c.callback 将 _cb作为键,值lua 回调函数 写入lua环境中
skynet_callback
lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_MAINTHREAD);
lua_State *gL = lua_tothread(L,-1);
cb_ud 保存 主线程,主线程不会被回收,生命周期同vm
主线程 栈上永远保存着两个值
traceback
回调函数
调用 回调函数
r = lua_pcall(L, 5, 0, 1);
栈上第一个函数作为 错误处理函数
主线程 调用回调函数 回调函数分配线程去处理 每条消息
7. 错误处理
在 发生错误的 服务 处理
回调函数发生在主线程
|