
Skynet is a multi-user Lua framework supporting the actor model.
skynet是云风的开源游戏服务端框架,服务了众多项目。但官方Wiki的入门教程实在糟糕,作为新手,看着头疼。近期打算用它实现一个具体的项目,顺便做一份新手教程。
本文所有测试,基于Debian和skynet 1.8.0。
skynet依赖jemalloc做内存分配器,所以需要 submodule update。而jemalloc编译需要autoconf。
# apt install make gcc g++ autoconf
$ git clone https://github.com/cloudwu/skynet.git
$ cd skynet
$ git checkout v1.8.0
$ git submodule update --init
$ make linux
skynet设计上是一款通用的网络服务引擎,通过传入不同的配置文件,启动不同的服务(service)。官方自带的example目录下,有很多配置文件。
一个skynet进程,会启动多个service,来组成完整的功能。以examples/config为例。
$ ./skynet examples/config
[:01000002] LAUNCH snlua bootstrap
[:01000003] LAUNCH snlua launcher
[:01000004] LAUNCH snlua cmaster
[:01000004] master listen socket 0.0.0.0:2013
[:01000005] LAUNCH snlua cslave
[:01000005] slave connect to master 127.0.0.1:2013
[:01000004] connect from 127.0.0.1:43642 4
[:01000006] LAUNCH harbor 1 16777221
[:01000004] Harbor 1 (fd=4) report 127.0.0.1:2526
[:01000005] Waiting for 0 harbors
[:01000005] Shakehand ready
[:01000007] LAUNCH snlua datacenterd
[:01000008] LAUNCH snlua service_mgr
[:01000009] LAUNCH snlua main
[:01000009] Server start
[:0100000a] LAUNCH snlua protoloader
[:0100000b] LAUNCH snlua console
[:0100000c] LAUNCH snlua debug_console 8000
[:0100000c] Start debug console at 127.0.0.1:8000
[:0100000d] LAUNCH snlua simpledb
[:0100000e] LAUNCH snlua watchdog
[:0100000f] LAUNCH snlua gate
[:0100000f] Listen on 0.0.0.0:8888
[:01000009] Watchdog listen on 0.0.0.0:8888
[:01000009] KILL self
[:01000002] KILL self
每一个"LAUNCH xxx"就对应启动了一个lua service。比如:"[:01000002] LAUNCH snlua bootstrap",其address为:01000002,对应文件:service/bootstrap.lua
启动流程如下,对应文件:examples/main.lua
main.lua (启动后退出)
├── protoloader — 协议 schema 共享
├── console — stdin 命令行
├── debug_console — TCP:8000 调试
├── simpledb — 内存 KV 数据库
└── watchdog — 连接管理
└── gate (TCP:8888) — 接受客户端
└── agent × N — 每客户端一个会话服务
通过telnet,直接登录debug console这个service,查看服务器进程的信息。对应文件:service/debug_console.lua
ps: 用Ctrl + ]让telnet断开与服务器的连接。
$ telnet localhost 8000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to skynet console
list
:01000004 snlua cmaster
:01000005 snlua cslave
:01000007 snlua datacenterd
:01000008 snlua service_mgr
:0100000a snlua protoloader
:0100000b snlua console
:0100000c snlua debug_console 8000
:0100000d snlua simpledb
:0100000e snlua watchdog
:0100000f snlua gate
<CMD OK>
mem
:01000004 61.28 Kb (snlua cmaster)
:01000005 65.98 Kb (snlua cslave)
:01000007 45.53 Kb (snlua datacenterd)
:01000008 54.17 Kb (snlua service_mgr)
:0100000a 236.03 Kb (snlua protoloader)
:0100000b 63.84 Kb (snlua console)
:0100000c 129.17 Kb (snlua debug_console 8000)
:0100000d 49.59 Kb (snlua simpledb)
:0100000e 48.04 Kb (snlua watchdog)
:0100000f 56.67 Kb (snlua gate)
<CMD OK>
^]
telnet> quit
Connection closed.
打开另一个shell,我们启动client,连接skynet进程。客户端/服务端形成了简单的echo功能,发送啥,服务端就回复啥。对应文件:examples/client.lua
下面我发送了Hello!
$ ./3rd/lua/lua examples/client.lua
Request: 1
Request: 2
RESPONSE 1
msg Welcome to skynet, I will send heartbeat every 5 sec.
RESPONSE 2
Hello!
Request: 3
RESPONSE 3
REQUEST heartbeat
REQUEST heartbeat
根据上面的例子,看看skynet的目录结构,省略了多余的目录和文件。
$ tree -L 2
.
├── cservice
│ ├── gate.so
│ ├── harbor.so
│ ├── logger.so
│ └── snlua.so
├── examples
│ ├── config
│ ├── config.path
│ ├── main.lua
│ ├── protoloader.lua
│ ├── simpledb.lua
│ └── watchdog.lua
├── luaclib
│ ├── bson.so
│ ├── client.so
│ ├── lpeg.so
│ ├── md5.so
│ ├── skynet.so
│ └── sproto.so
├── lualib
│ ├── loader.lua
│ ├── md5.lua
│ ├── skynet.lua
│ ├── sprotoloader.lua
│ ├── sproto.lua
│ └── sprotoparser.lua
└── service
├── bootstrap.lua
├── cmaster.lua
├── console.lua
├── cslave.lua
├── datacenterd.lua
├── debug_console.lua
├── launcher.lua
└── snaxd.lua
提交了PR,把skynet移植到OpenBSD:#2157
Last Update: 2026.06.02