1.skynet消息基本组成
每个 skynet 服务,最重要的职责就是处理别的服务发送过来的消息,以及向别的服务发送消息。每条 skynet 消息由五个元素构成。
1.1 session 消息标识
大部分消息工作在请求回应模式下。一个服务向另一个服务发起一个请求,而后收到请求的服务在处理完请求消息后,回复一条消息。session 是由发起请求的服务生成的,对它自己唯一的消息标识。回应方在回应时,将 session 带回。这样发送方才能识别出哪条消息是针对哪条的回应。session 是一个非负整数,当一条消息不需要回应时,按惯例,使用 0 这个特殊的 session 号。session 由 skynet 框架生成管理,通常不需要使用者关心。
1.2 source 消息源
每个服务都由一个 32bit 整数标识。这个整数可以看成是服务在 skynet 系统中的地址。即使在服务退出后,新启动的服务通常也不会使用已用过的地址,每条收到的消息都携带有 source ,方便在回应的时候可以指定地址。但地址的管理通常由框架完成,用户不用关心。
(1)type :消息类别
每个服务可以接收 256 种不同类别的消息。每种类别可以有不同的消息编码格式。有十几种类别是框架保留的,通常也不建议用户定义新的消息类别。因为用户完全可以利用已有的类别,而用具体的消息内容来区分每条具体的含义。框架把这些 type 映射为字符串便于记忆。最常用的消息类别名为 “lua” 广泛用于用 lua 编写的 skynet 服务间的通讯。
(2)messsage :消息的 C 指针
在 Lua 层看来是一个 lightuserdata 。框架会隐藏这个细节,最终用户处理的是经过解码过的 lua 对象。只有极少情况,你才需要在 lua 层直接操作这个指针。
(3)size :消息的长度
通常和 message 一起结合起来使用。skynet.manager 共享 skynet 名字空间。require 这个模块后,这些额外的 API 依旧放在 skynet 下。而 require “skynet.manager” 的返回值同样是 skynet 名字空间。
其他一些API的解释:
skynet.launch 启动一个 C 服务。
skynet.kill 强行杀掉一个服务。
skynet.abort 退出 skynet 进程。
skynet.register 给自身注册一个名字。
skynet.name 为一个服务命名。
skynet.forward_type将本服务实现为消息转发器,对一类消息进行转发。
skynet.filter 过滤消息再处理。(注:filter 可以将 type, msg, sz, session, source 五个参数先处理过再返回新的 5 个参数。)
skynet.monitor 给当前 skynet 进程设置一个全局的服务监控。
2.examples源码解析
2.1 main.lua
(1)skynet.start()用于服务的入口,加载lua服务时先运行这里的代码,它调用了luaclib-src/lua_skynet.c里面的callback(),最终调用Skynet的框架skynet_callback()来设置回调函数
(2)skynet.newservice()用于启动一个lua写的服务,省略掉.lua后缀名。它调用了skynet.call()然后skynet.call()调用luaclib-src/lua_skynet.c
里面的send(),最终调用Skynet的框架skynet_send()压入队列
(3)skynet.call()用于发送一条消息给Skynet的框架。消息会压入队列,等待Skynet框架的调度。
(4)skynet.exit()移除服务,通过skynet.send()发送一条消息给Skynet框架来移除lua的这个服务。
(5)skynet.monitor() 用于监视服务,看它是否关闭
main.lua一共打开了四个服务:
1、service_mgr 这个是系统的模块,用于管理服务。
2、console 这个是系统的模块,用于输出。
3、simpledb 这个是例子的模块,用于管理Key–Value数据。
4、watchdog 这个是例子的模块,用于监视socket端口,等待数据。
2.2 watchdog.lua
skynet.dispatch()这个服务的回调函数,通过SOCKET[]来调用函数,这些函数有:
(1)SOCKET.open() 打开agent服务并启动,使用gate来管理socket。
(gate服务器:gate 服务启动后,并非立刻开始监听。要让 gate 服务器开启监听端口,可以通过 lua 协议向它发送一个 open 指令,附带一个启动参数表)
(2)SOCKET.close() 关闭agent服务。
(3)SOCKET.error() 打印错误信息。
(4)SOCKET.data() 有数据到来
2.3 agent.lua
watchdog调用SOCKET.open()的时候就调用了这里的CMD.start(),在客户端输出了”Welcome to skynet”。
Agent的核心就是注册了协议,并根据协议把数据发送给simpledb服务去处理
2.4 simple.db
以上是简单的set和get方法