下载安装
- 源码: https://github.com/cloudwu/skynet
- 编译:https://github.com/cloudwu/skynet/wiki/Build
服务器 demo
新建 server 目录,将 skynet 原来克隆在 server 目录中;为了后面维护和更新方便,在 skynet 目录同级新建 game 目录 和 log 目录;在 game 目录中新建3个文件,config、main.lua 和 service_gate.lua;log 目录是存放日志文件,最终目录结构如下:
server
+-- skynet
|-- ...
+-- ...
+-- game
|-- config
|-- main.lua
|-- service_gate.lua
+-- log
config 配置说明参考: https://github.com/cloudwu/skynet/wiki/Config
下面是我的配置:
-- 非配置项,单纯的定义一个了根目录变量,方便后面目录的配置和修改
root="./"
-- 必须配置,skynet 启动的第一个服务以及其启动参数
bootstrap = "snlua bootstrap"
-- 必须配置,工作线程数,不要多余 cpu 核数
thread = 1
-- 必须配置,用 C 编写的服务模块的位置
cpath = root.."cservice/?.so"
-- skynet_error的输出文件,默认为nil表示标准输出
logger = "../game/log/game.log"
-- 当你运行时为一个服务打开 log 时,这个服务所有的输入消息都会被记录在这个目录下,文件名为服务地址
logpath = "../game/log"
-- 0表示单节点模式,1-255 间的任意整数表示多节点模式
harbor = 0
-- lua 脚本所在的位置
luaservice = root.."service/?.lua;"..root.."../game/?.lua"
-- 启动脚本,必须在luaservice指定的路径中,默认为 main.lua
start = "main"
下面是一个最简单的服务,使用 socket 监听客户端请求,返回一个字符串给客户端,写在 service_gate.lua 中。
local skynet = require "skynet"
local socket = require "skynet.socket"
function accept(id, addr)
print("accept connect from addr: " .. addr .. " id: " .. id)
-- 每当 accept 函数获得一个新的 socket id 后,并不会立即收到这个 socket 上的数据。
-- 这是因为,我们有时会希望把这个 socket 的操作权转让给别的服务去处理。
-- 任何一个服务只有在调用 socket.start(id) 之后,才可以收到这个 socket 上的数据。
socket.start(id)
while true do
-- 读取客户端发过来的数据
local msg = socket.read(id)
if msg then
print(msg)
-- 把一个字符串置入正常的写队列,skynet 框架会在 socket 可写时发送它
socket.write(id, "msg from server")
else
socket.close(id)
return
end
end
end
skynet.start(function()
local listen_id = socket.listen("0.0.0.0", 8888)
-- 接收到客户端连接或发送消息
socket.start(listen_id , accept)
end)
启动服务
在配置中指定了启动脚本 main.lua,在其中启动我们上面的这个服务,其内容如下:
local skynet = require "skynet"
-- skynet.start(启动函数) 启动服务
skynet.start(function()
-- skynet.newservice(服务脚本文件名)启动一个新的 lua 服务
skynet.newservice("service_gate")
skynet.exit()
end)
测试
推荐一个socket测试工具:https://sokit.soft32.com/
填好ip和端口,点击tcp链接,然后在buffer data中随便写点什么,点击send,可以得到如下结果: