skynet 环境搭建、启动、自定义Demo

发布时间:2024-04-30 18:07:50 作者:yexindonglai@163.com 阅读(159)

前置准备

因为这里使用的linux版本的skynet,所以需要先准备linux环境,我使用的是 ubuntu 22.04 LTS 版本,是在微软商店下载的;

skynet是使用c语言编写的网络库,需要先安装编译的条件

  1. # c语言编译工具
  2. apt install gcc -y
  3. # 安装构建工具
  4. apt install make -y

安装 skynet

github地址:https://github.com/cloudwu/skynet

源码安装

下载源码, 这里指定 v1.7.0版本

  1. git clone https://github.com/cloudwu/skynet.git
  2. cd skynet
  3. git checkout v1.7.0
  4. # 下载子项目的代码
  5. git submodule update --init --recursive

以上是使用github 进行下载,若因为网络问题无法下载,可使用国内的网站下载

  1. # 下载skynet
  2. git clone https://gitcode.com/cloudwu/skynet.git
  3. cd skynet
  4. # 切换到最新版本
  5. git checkout v1.7.0
  6. # 下载子项目的代码
  7. cd 3rd
  8. git clone https://gitcode.com/jemalloc/jemalloc.git

目录说明

  • 3rd:存放第三方的代码,如Lua、jemalloc、lpeg等。
  • cservice:存放内置的用c语言编写的服务,如gate、harbor、snlua等。
  • examples:范例。
  • luaclib:用c语言编写的程序库,如bson解析、md5解析等
  • lualib:用Lua编写的程序库。
  • lualib-src:luaclib目录下,库文件的源码。
  • service:包含skynet内置的一些服务。用Lua编写的服务。
  • service-src:cservice目录下,程序代的源码。
  • skynet-src:用c写的skynet核心代码。
  • test:测试代码。

编译

  1. # 进入目录进行编译
  2. cd skynet
  3. make linux

报错解决

autoreconf: not found

若报错以下信息,是因为 没有安装 automake, just to do below:

  1. make all PLAT=linux SKYNET_LIBS="-lpthread -lm -ldl -lrt" SHARED="-fPIC --shared" EXPORT="-Wl,-E" MALLOC_STATICLIB="3rd/jemalloc/lib/libjemalloc_pic.a" SKYNET_DEFINES=""
  2. make[1]: Entering directory '/root/skynet'
  3. cd 3rd/jemalloc && ./autogen.sh --with-jemalloc-prefix=je_ --enable-prof
  4. autoconf
  5. ./autogen.sh: 5: autoconf: not found
  6. Error 0 in autoconf
  7. make[1]: *** [Makefile:44: 3rd/jemalloc/Makefile] Error 1
  8. make[1]: Leaving directory '/root/skynet'
  9. make: *** [platform.mk:40: linux] Error 2

解决方案
执行以下命令即可

  1. sudo apt-get install autoconf automake libtool -y

然后继续执行 make linux 命令

启动

编译完成后会在当前目录下生成一个名为 skynet 的可执行文件, 输入./skynet ./examples/config命令即可运行,当展示以下信息时表示已运行成功,端口号为:8080

  1. root@PAw9033927:~/skynet# ./skynet ./examples/config
  2. [:01000002] LAUNCH snlua bootstrap
  3. [:01000003] LAUNCH snlua launcher
  4. [:01000004] LAUNCH snlua cmaster
  5. [:01000004] master listen socket 0.0.0.0:2013
  6. [:01000005] LAUNCH snlua cslave
  7. [:01000005] slave connect to master 127.0.0.1:2013
  8. [:01000004] connect from 127.0.0.1:65512 4
  9. [:01000006] LAUNCH harbor 1 16777221
  10. [:01000004] Harbor 1 (fd=4) report 127.0.0.1:2526
  11. [:01000005] Waiting for 0 harbors
  12. [:01000005] Shakehand ready
  13. [:01000007] LAUNCH snlua datacenterd
  14. [:01000008] LAUNCH snlua service_mgr
  15. [:01000009] LAUNCH snlua main
  16. [:01000009] Server start
  17. [:0100000a] LAUNCH snlua protoloader
  18. [:0100000b] LAUNCH snlua console
  19. [:0100000c] LAUNCH snlua debug_console 8000
  20. [:0100000c] Start debug console at 127.0.0.1:8000
  21. [:0100000d] LAUNCH snlua simpledb
  22. [:0100000e] LAUNCH snlua watchdog
  23. [:0100000f] LAUNCH snlua gate
  24. [:0100000f] Listen on 0.0.0.0:8888
  25. [:01000009] Watchdog listen on 0.0.0.0:8888
  26. [:01000009] KILL self
  27. [:01000002] KILL self

连接

执行如下命令,每隔5秒就会给服务端发送一个heartbeat心跳包,

  1. ./3rd/lua/lua examples/client.lua

如下 ,输入 hello 后会返回一个 world 字符

  1. root@PAw9033927:~/skynet# ./3rd/lua/lua examples/client.lua
  2. Request: 1
  3. Request: 2
  4. RESPONSE 1
  5. msg Welcome to skynet, I will send heartbeat every 5 sec.
  6. RESPONSE 2
  7. REQUEST heartbeat
  8. REQUEST heartbeat
  9. hello # 发送
  10. Request: 3
  11. RESPONSE 3
  12. result world # skynet返回的结果
  13. REQUEST heartbeat
  14. REQUEST heartbeat

写个Demo

想要自己写个Demo,得先知道skynet是如何工作的。

1、配置文件

运行skynet时,需要制定一个配置文件,例:

  1. ./skynet example/config

我们先看看这个config文件里面是啥,进入examples目录,打开config文件,内容如下

  1. include "config.path"
  2. -- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
  3. thread = 8
  4. logger = nil
  5. logpath = "."
  6. harbor = 1
  7. address = "127.0.0.1:2526"
  8. master = "127.0.0.1:2013"
  9. start = "main" -- main script
  10. bootstrap = "snlua bootstrap" -- The service for bootstrap
  11. standalone = "0.0.0.0:2013"
  12. -- snax_interface_g = "snax_g"
  13. cpath = root.."cservice/?.so"
  14. -- daemon = "./skynet.pid"

第一行引用了config.path文件,我们打开config.path文件,内容如下:

  1. root = "./"
  2. luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua;"..root.."test/?/init.lua"
  3. lualoader = root .. "lualib/loader.lua"
  4. lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
  5. lua_cpath = root .. "luaclib/?.so"
  6. snax = root.."examples/?.lua;"..root.."test/?.lua"

现在,我们把 config 、config.path 两个文件合在一起看,如下:

  1. root = "./"
  2. luaservice = root.."service/?.lua;"..root.."test/?.lua;"..root.."examples/?.lua;"..root.."test/?/init.lua"
  3. lualoader = root .. "lualib/loader.lua"
  4. lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
  5. lua_cpath = root .. "luaclib/?.so"
  6. snax = root.."examples/?.lua;"..root.."test/?.lua"
  7. -- preload = "./examples/preload.lua" -- run preload.lua before every lua service run
  8. thread = 8
  9. logger = nil
  10. logpath = "."
  11. harbor = 1
  12. address = "127.0.0.1:2526"
  13. master = "127.0.0.1:2013"
  14. start = "main" -- main script
  15. bootstrap = "snlua bootstrap" -- The service for bootstrap
  16. standalone = "0.0.0.0:2013"
  17. -- snax_interface_g = "snax_g"
  18. cpath = root.."cservice/?.so"
  19. -- daemon = "./skynet.pid"

这里对几个重要的参数做一下说明:

参数 描述
thread 设置工作线程数
luaservice 服务脚本路径,包含 skynet 自带的服务和自己写的服务
lualoader lua脚本加载器,指的是用哪一段 lua 代码加载 lua 服务。通常配置为 lualib/loader.lua ,再由这段代码解析服务名称,进一步加载 lua 代码。snlua 会将下面几个配置项取出,放在初始化好的 lua 虚拟机的全局变量中。具体可参考实现。
lua_path 程序加载lua脚本时会搜索 lua_path 路径,将其添加到 package.path 中的路径,供 require 调用。
lua_cpath 用c语言编写的程序库(.so文件)路径, 将其添加到 package.cpath 路径,供 require 调用。
harbor 可选项,用于指定当前节点的节点号。节点号用于标识节点之间的通信。如果不设置该项,Skynet将自动分配节点号。skynet后期提供了更适用的 cluster 模式,建议适用cluster,配 0
snax snax模版路径
logger 若将logger配置项设置为nil表示禁用日志记录功能
logpath 指定日志文件的保存路径。可以是绝对路径或相对路径。如果设置为nil或空字符串,则日志文件将保存在Skynet启动目录下的./log文件夹中。
address 当前 skynet 节点的地址和端口,方便其它节点和它组网。注:即使你只使用一个节点,也需要开启控制中心,并额外配置这个节点的地址和端口。
master 指定 skynet 控制中心的地址和端口,如果你配置了 standalone 项,那么这一项通常和 standalone 相同。
start 主服务入口, 这是 bootstrap 最后一个环节将启动的 lua 服务,也就是你定制的 skynet 节点的主程序。默认为 main ,即启动 main.lua 这个脚本。这个 lua 服务的路径由下面的 luaservice 指定。
bootstrap 启动的第一个服务以及其启动参数。默认配置为 snlua bootstrap ,即启动一个名为 bootstrap 的 lua 服务。通常指的是 service/bootstrap.lua 这段代码。
standalone 如果把这个 skynet 进程作为主进程启动(skynet 可以由分布在多台机器上的多个进程构成网络),那么需要配置standalone 这一项,表示这个进程是主节点,它需要开启一个控制中心,监听一个端口,让其它节点接入。
cpath 用 C 编写的服务模块的位置,通常指 cservice 下那些 .so 文件。如果你的系统的动态库不是以 .so 为后缀,需要做相应的修改。这个路径可以配置多项,以 ; 分割。

在skynet根目录下新建一个new_example目录,在里面创建 config.node1 文件

  1. root@PAw9033927:~/skynet# mkdir new_example
  2. root@PAw9033927:~/skynet# ls -l
  3. total 8388
  4. drwxr-xr-x 1 root root 4096 Apr 30 17:44 3rd
  5. -rw-r--r-- 1 root root 13727 Apr 30 18:19 HISTORY.md
  6. -rw-r--r-- 1 root root 1085 Apr 30 17:44 LICENSE
  7. -rw-r--r-- 1 root root 3805 Apr 30 17:44 Makefile
  8. -rw-r--r-- 1 root root 1656 Apr 30 18:19 README.md
  9. drwxr-xr-x 1 root root 4096 Apr 30 17:47 cservice
  10. drwxr-xr-x 1 root root 4096 May 7 15:42 examples
  11. drwxr-xr-x 1 root root 4096 Apr 30 17:47 luaclib
  12. drwxr-xr-x 1 root root 4096 Apr 30 18:19 lualib
  13. drwxr-xr-x 1 root root 4096 Apr 30 18:19 lualib-src
  14. drwxr-xr-x 1 root root 4096 May 13 18:24 new_example
  15. -rw-r--r-- 1 root root 876 Apr 30 17:44 platform.mk
  16. drwxr-xr-x 1 root root 4096 Apr 30 18:19 service
  17. drwxr-xr-x 1 root root 4096 Apr 30 18:19 service-src
  18. -rwxr-xr-x 1 root root 8555832 Apr 30 17:47 skynet
  19. drwxr-xr-x 1 root root 4096 Apr 30 18:19 skynet-src
  20. drwxr-xr-x 1 root root 4096 Apr 30 18:19 test
  21. root@PAw9033927:~/skynet# cd new_example
  22. root@PAw9033927:~/skynet# touch config.node1

config.node1 内容如下

  1. thread = 4
  2. cpath = "./cservice/?.so"
  3. bootstrap = "snlua bootstrap"
  4. start = "main"
  5. harbor = 0
  6. lualoader = "./lualib/loader.lua"
  7. luaservice = "./service/?.lua;" .. "./new_example/service/?/init.lua;" .. "./new_example/service/?.lua;"
  8. lua_path = "./etc/?.lua;" .. "./lualib/?.lua;" .. "./lualib/?.lua;" .. "./lualib/?/init.lua;"
  9. lua_cpath = "./luaclib/?.so;" .. "./luaclib/?.so"

1.1、问号 (?) 的作用

在 config.node1 配置的服务脚本路径中,luaservice 有几个 ? 匹配符,这其实是用来匹配服务名用的; 主服务入口 配置的是 main

  1. # 主服务入口
  2. start = main
  3. # 服务脚本路径
  4. luaservice = "./service/?.lua;" .. "./new_example/service/?/init.lua;" .. "./new_example/service/?.lua;"

根据问号匹配符, skynet 启动后会根据以下顺序执行

  1. 先找 ./service/main.lua 文件,若文件存在就会执行
  2. 若找不到,就会去找 ./new_example/service/main/init.lua 文件,,若文件存在就会执行
  3. 若找不到,就会去找 ./new_example/service/main.lua,若文件存在就会执行
  4. 若以上三个文件都找不大到,在启动 skynet 时会报错:
  1. [:00000008] lua loader error : ./lualib/loader.lua:24:
  2. cannot open ./service/main.lua: No such file or directory
  3. cannot open ./new_example/service/main/init.lua: No such file or directory
  4. cannot open ./new_example/service/main.lua: No such file or directory
  5. stack traceback:
  6. [C]: in function 'error'
  7. ./lualib/loader.lua:24: in main chunk

2、主服务

上面我们配置的主服务是main,

  1. start = "main"

它会去配置的luaservice路径中查找一个main.lua脚本; 框架会去启动这个main服务,我们现在还没有这个main.lua脚本,现在我们就来写这个main.lua脚本,在刚刚新建的 new_example 目录下新建一个 service 目录,service 目录新建一个main.lua的文件;

  1. root@PAw9033927:~/skynet# cd new_example
  2. root@PAw9033927:~/skynet# mkdir service
  3. root@PAw9033927:~/skynet# touch main.lua

main.lua 内容如下

  1. local skynet = require "skynet"
  2. skynet.start(function()
  3. skynet.error("[start main] hello world skynet,I'm coming!")
  4. -- TODO 启动其他服务
  5. skynet.exit()
  6. end)

3、运行

回到 skynet 根目录,执行命令 ./skynet new_example/config.node1 后就可以看到控制台输出的内容了

  1. root@PAw9033927:~/skynet# ./skynet new_example/config.node1
  2. [:00000002] LAUNCH snlua bootstrap
  3. [:00000003] LAUNCH snlua launcher
  4. [:00000004] LAUNCH snlua cdummy
  5. [:00000005] LAUNCH harbor 0 4
  6. [:00000006] LAUNCH snlua datacenterd
  7. [:00000007] LAUNCH snlua service_mgr
  8. [:00000008] LAUNCH snlua main
  9. [:00000008] [start main] hello world skynet,I'm coming!
  10. [:00000008] KILL self
  11. [:00000002] KILL self

写个打工的服务

1、新建打工服务

我们将打工服务 命名为 worker,在 new_example/service 目录下新建一个目录,命名为 worker,进入worker目录,新建一个init.lua 文件,

  1. cd new_example/service
  2. mkdir worker
  3. cd worker
  4. touch init.lua

init.lua 文件内容如下

  1. -- service/worker/init.lua脚本
  2. local skynet = require "skynet"
  3. -- 消息响应函数表
  4. local CMD = {}
  5. -- 服务名
  6. local worker_name = ""
  7. -- 服务id
  8. local worker_id = ""
  9. -- 工钱
  10. local money = 0
  11. -- 是否在工作
  12. local isworking = false
  13. -- 每帧调用,一帧的时间是0.2
  14. local function update(frame)
  15. if isworking then
  16. money = money + 1
  17. skynet.error(worker_name .. tostring(worker_id) .. ", money: " .. tostring(money))
  18. end
  19. end
  20. -- 死循环定时器,每隔0.2秒调用一次update函数
  21. local function timer()
  22. local stime = skynet.now()
  23. local frame = 0
  24. while true do
  25. frame = frame + 1
  26. -- pcall Lua 中的一个函数,用于捕获并处理函数调用过程中的错误。它的作用是在保护模式下调用一个函数,如果函数执行过程中发生错误,pcall 将捕获错误并返回错误信息,而不是中断程序的执行。
  27. -- 调用 update函数
  28. local isok, err = pcall(update, frame)
  29. if not isok then
  30. skynet.error(err)
  31. end
  32. -- 睡眠0.2秒,这个sleep单位是10ms起步的,如果输入1,就是延时10ms,如果输入10就是延时100ms,如果输入100,就是延时1
  33. skynet.sleep(20)
  34. end
  35. end
  36. -- 初始化
  37. local function init(name, id)
  38. worker_name = name
  39. worker_id = id
  40. end
  41. -- 开始工作
  42. function CMD.start_work(source)
  43. isworking = true
  44. end
  45. -- 停止工作
  46. function CMD.stop_work(source)
  47. isworking = false
  48. end
  49. -- 调用初始化函数,...是不定参数,会从skynet.newservice的第二个参数开始透传过来
  50. init(...)
  51. skynet.start(function()
  52. -- 消息分发
  53. skynet.dispatch("lua", function(session, source, cmd, ...)
  54. -- CMD这个表中查找是否有定义响应函数,如果有,则触发响应函数
  55. local func = CMD[cmd]
  56. if func then
  57. func(source, ...)
  58. end
  59. end)
  60. -- 开启一个协程启动定时器,里面是个死循环,会一直执行
  61. skynet.fork(timer)
  62. end)

2、在主服务启动打工服务

我们回到主服务main.lua脚本中,添加一句skynet.newservice调用,如下:

  1. -- main.lua脚本
  2. local skynet = require "skynet"
  3. skynet.start(function ()
  4. skynet.error("[start main] hello world")
  5. -- 启动打工服务,其中第二个参数和第三个参数会透传给 new_example/service/worker/init.lua 脚本
  6. local worker1 = skynet.newservice("worker", "worker", 1)
  7. skynet.exit()
  8. end)

现在我们测试一下,在根目录中执行命令

  1. ./skynet ./new_example/config_node1

运行效果如下,可以看到启动了一个worker服务

  1. root@yexindong:~/skynet# ./skynet ./new_example/config_node1
  2. [:00000002] LAUNCH snlua bootstrap
  3. [:00000003] LAUNCH snlua launcher
  4. [:00000004] LAUNCH snlua cdummy
  5. [:00000005] LAUNCH harbor 0 4
  6. [:00000006] LAUNCH snlua datacenterd
  7. [:00000007] LAUNCH snlua service_mgr
  8. [:00000008] LAUNCH snlua main
  9. [:00000008] [start main] hello world skynet,I'm coming!
  10. [:00000009] LAUNCH snlua worker worker 1 # 这是启动的worker 服务
  11. [:00000008] KILL self
  12. [:00000002] KILL self

有同学可能会问了,我们调用skynet.newservice时第一个参数是worker,框架怎么知道会去执行service/worker/init.lua脚本呢?

还记得我们的config.node1配置吗,里面的luaservice我们配置了”./service/?/init.lua;”,如下:

  1. -- config.node1配置
  2. luaservice = "./service/?.lua;" .. "./new_example/service/?/init.lua;" .. "./new_example/service/?.lua;"

其中,? 符号会匹配服务名,也就是说,当我们调用skynet.newservice(“worker”)时,框架先去检查./service/worker.lua脚本是否存在,发现不存在,于是接着检查./new_example/service/worker/init.lua脚本,发现存在,于是执行./new_example/service/worker/init.lua脚本作为worker服务,当然,如果找不到,它就会去检查./new_example/service/worker.lua是否存在了。

另外,newservice的函数原型是newservice(name, …),我们调用skynet.newservice时可以透传一些参数给服务,比如我们上面的

  1. -- main.lua脚本
  2. local worker1 = skynet.newservice("worker", "worker", 1)

第一个参数是服务名,第二个参数和第三个参数就会透传给init.lua脚本,我们在init.lua脚本中可以取出来缓存起来,如下:

  1. -- new_example/service/worker/init.lua脚本
  2. -- 服务名
  3. local worker_name = ""
  4. -- 服务id
  5. local worker_id = ""
  6. local function init(name, id)
  7. worker_name = name
  8. worker_id = id
  9. end
  10. -- 执行init函数,... skynet.newservice 透传过来第23个参数
  11. init(...)

3、在主服务给打工服务发消息

打工服务中我们定义了两个消息:start_work 和 stop_work,现在我们在主服务中给打工服务发送消息,添加skynet.send调用,如下:

  1. local skynet = require "skynet"
  2. skynet.start(function ()
  3. skynet.error("[start main] hello world")
  4. -- 启动打工服务,其中第二个参数和第三个参数会透传给service/worker/init.lua脚本
  5. local worker1 = skynet.newservice("worker", "worker", 1)
  6. -- 开始工作 - send是发送消息,不会阻塞调用方
  7. skynet.send(worker1, "lua", "start_work")
  8. -- 主服务休息2秒,注意,这里是主服务休息2秒,并不会卡住worker服务,这个sleep单位是10ms起步的,如果输入1,就是延时10ms,如果输入10就是延时100ms,如果输入100,就是延时1
  9. skynet.sleep(200)
  10. -- 2秒后停止工作
  11. skynet.send(worker1, "lua", "stop_work")
  12. skynet.exit()
  13. end)

在执行一下命令

  1. ./skynet ./new_example/config_node1

输出结果如下, 2秒赚了10块钱

  1. root@yexindong:~/skynet# ./skynet ./new_example/config_node1
  2. [:00000002] LAUNCH snlua bootstrap
  3. [:00000003] LAUNCH snlua launcher
  4. [:00000004] LAUNCH snlua cdummy
  5. [:00000005] LAUNCH harbor 0 4
  6. [:00000006] LAUNCH snlua datacenterd
  7. [:00000007] LAUNCH snlua service_mgr
  8. [:00000008] LAUNCH snlua main
  9. [:00000008] [start main] hello world skynet,I'm coming!
  10. [:00000009] LAUNCH snlua worker worker 1
  11. [:00000009] worker1, money: 1
  12. [:00000009] worker1, money: 2
  13. [:00000009] worker1, money: 3
  14. [:00000009] worker1, money: 4
  15. [:00000009] worker1, money: 5
  16. [:00000009] worker1, money: 6
  17. [:00000009] worker1, money: 7
  18. [:00000009] worker1, money: 8
  19. [:00000009] worker1, money: 9
  20. [:00000008] KILL self
  21. [:00000009] worker1, money: 10
  22. [:00000002] KILL self

4、添加网络模块

写服务端,肯定需要涉及到网络模块,需要用到skynet.socket,以下是简单的案例:

  1. -- main.lua
  2. local skynet = require "skynet"
  3. local socket = require "skynet.socket"
  4. local function on_connect(fd, addr)
  5. socket.start(fd)
  6. while true do
  7. local readdata = socket.read(fd)
  8. if readdata then
  9. -- TODO 处理消息
  10. print("read data:" .. readdata)
  11. -- 回应客户端,把readdata返回给客户端
  12. socket.write(fd, "server get data: " .. readdata)
  13. else
  14. -- 连接断开了
  15. socket.close(fd)
  16. end
  17. end
  18. end
  19. skynet.start(function()
  20. local listenfd = socket.listen("0.0.0.0", 8888)
  21. socket.start(listenfd, on_connect)
  22. end)

5、打工服务和网络模块的结合

刚刚的打工服务是由服务端来开启的,那么现在我们需要改一下,由用户来发起打工;

修改下main.lua的代码如下,其他代码无需修改

  1. local skynet = require "skynet"
  2. local socket = require "skynet.socket"
  3. local function on_connect(fd, addr)
  4. -- 启动打工服务,其中第二个参数和第三个参数会透传给 new_example/service/worker/init.lua脚本
  5. local worker1 = skynet.newservice("worker", "worker", 1)
  6. socket.start(fd)
  7. while true do
  8. local readdata = socket.read(fd)
  9. if readdata then
  10. -- TODO 处理消息
  11. print("收到命令:" .. readdata)
  12. -- 去掉换行符
  13. readdata = string.gsub(readdata,"\r\n","")
  14. readdata = string.gsub(readdata,"\n","")
  15. -- 去掉空格
  16. readdata = string.gsub(readdata," ","")
  17. -- 开始工作
  18. skynet.send(worker1, "lua", readdata)
  19. -- 主服务休息2秒,注意,这里是主服务休息2秒,并不会卡住worker服务
  20. skynet.sleep(200)
  21. skynet.send(worker1, "lua", "stop_work")
  22. -- 告诉客户端,命令执行成功了
  23. socket.write(fd, readdata .. " order execute success!")
  24. else
  25. -- 连接断开了
  26. socket.close(fd)
  27. end
  28. end
  29. end
  30. skynet.start(function()
  31. local listenfd = socket.listen("0.0.0.0", 8888)
  32. socket.start(listenfd, on_connect)
  33. end)

然后,我们再次运行启动命令

  1. ./skynet ./new_example/config_node1

使用linux 的 telnet工具连接skynet,连接成功后直接输入start_work

  1. telnet 127.0.0.1 8888

执行后结果如下

  1. root@yexindong:~# telnet 127.0.0.1 8888
  2. Trying 127.0.0.1...
  3. Connected to 127.0.0.1.
  4. Escape character is '^]'.
  5. start_work
  6. start_work order execute success!

服务端的响应如下, 可以看到服务端开始打工了,最后赚到了10块钱

  1. root@yexindong:~/skynet# ./skynet ./new_example/config_node1
  2. [:00000002] LAUNCH snlua bootstrap
  3. [:00000003] LAUNCH snlua launcher
  4. [:00000004] LAUNCH snlua cdummy
  5. [:00000005] LAUNCH harbor 0 4
  6. [:00000006] LAUNCH snlua datacenterd
  7. [:00000007] LAUNCH snlua service_mgr
  8. [:00000008] LAUNCH snlua main
  9. [:00000002] KILL self
  10. [:0000000a] LAUNCH snlua worker worker 1
  11. 收到命令:start_work
  12. [:0000000a] worker1, money: 1
  13. [:0000000a] worker1, money: 2
  14. [:0000000a] worker1, money: 3
  15. [:0000000a] worker1, money: 4
  16. [:0000000a] worker1, money: 5
  17. [:0000000a] worker1, money: 6
  18. [:0000000a] worker1, money: 7
  19. [:0000000a] worker1, money: 8
  20. [:0000000a] worker1, money: 9
  21. [:0000000a] worker1, money: 10

原文:https://zhuanlan.zhihu.com/p/661868672

关键字skynet