Skynet服务器框架(九) snax框架
什么是 snax
由于 skynet 的 API 还是比较偏底层,为简化服务的编写提供一套简单的 API ,便有了这套 snax
框架,解决的问题:
“编写一个
skynet
内部服务,处理发送给它的消息。snax
并不会取代skynet
原有的 api ,只是方便实现这类简单需求而已。”—— 云风
换句话说,snax
就是对 skynet API 的部分封装而产生的一个框架
编写 skynet 服务:
在了解如何使用 snax
来编写一个服务之前,先大致了解一下直接使用 skynet 的 API 是如何创建一个服务的,这里服务仅实现消息响应部分的功能:
通常是在
skynet.start
中会调用skynet.dispatch
接口:skynet.start(function() skynet.dispatch("lua", function(session, address, ...) dispatch(...) end)
首先,用
skynet.start
来注册 skynet 服务的启动函数,并确定这个服务用什么协议来解析消息(一般选择“lua”
协议,因为这种协议是为 lua 设计的,可以最高效地把 lua 原生数据序列化);然后,规定消息的第一个传入数据为字符串,表示消息类型,利用此类型区分不同消息的响应:
local command = {} function command.foobar(...) end local function dispatch(cmd, ...) command[cmd](...) end
skynet 内部的消息分两种:
- 单向推送
skynet.send
- 发起请求,等待回应
skynet.call
对于请求的回应操作,使用
skynet.ret
接口来实现,但此 API 并不负责数据打包。所以,如果使用 lua 协议,通常写成skynet.ret(skynet.pack(...))
的形式,以完成数据打包
和回应请求
这两个步骤。- 单向推送
为了兼容
skynet.send
和skynet.call
的调用需求,需要对dispatch
做一下优化:local function dispatch(cmd, ...) --先判断command函数集中包不包含当前传入 cmd 的处理函数,假如未定义则不再往下执行 local f = assert(command[cmd]) --执行 cmd 对应的处理函数 local r = f(...) --判断是否有返回结果 if r ~= NORET then --打包数据并回传给消息发送方 skynet.ret(skynet.pack(r)) end end
启动 skynet 服务的接口:
skynet.newservice(name,...)
这里
name
是服务对应的.lua
文件的名称。
编写 snax 服务:
1.配置:
要使用 snax
框架来编写我们的服务,首先需要在 Config
中配置 snax
参数项,配置内容是查找使用 snax 框架格式编写的服务文件的目录。
2.格式要求:
每个 snax
服务都有一个用于启动服务的名字,推荐按 lua 的模块命名规则,但目前不推荐服务名中包含”点”(在路径搜索上尚未支持 .
与 /
的替换)。在启动服务时会按查找路径搜索对应的文件。
snax
服务用 lua 编写,但并不是一个独立的 lua 程序。它里面包含了一组 lua 函数,会被 snax
框架分析加载。
3.使用 snax
框架:
snax
框架是把一些通用代码放到一个简单的框架中而得到的一个更易于使用的 API 。看完了 skynet API 的实现过程之后,我们再用 snax
来编写一个功能完全相同的服务,然后进行对比讲解:
-- foobar服务
local i = 0
local hello = "hello"
function response.echo(data)
return data, i
end
function subscribe.touch()
i = i + 1
end
function init( ... )
print ("service start:", ...)
end
function exit(...)
print ("service exit:", ...)
end
init()
:启动此服务时会调用此函数,并把启动参数传给它,这是每个 snax 服务都必须定义的;exit()
:这是此 snax 服务退出要执行的代码,通常用于响应服务退出时间,同样也可以传入一些参数;response.
:以response.
开头的函数表示返回值会通过调用skynet.ret
返回;subscribe.
:以subscribe.
开头的函数表示返回值会被扔掉不会返回。
关于 snax 的传入参数,并没有对类型设置项目,可以传入 lua 的复杂数据类型,而 skynet 服务则受限于底层C源码限制,只接受传入字符串类型的启动参数。
4.snax
服务API:
这里以上面写的 snax 服务为例,启动该服务并调用该服务的内部函数:
--启动服务
local p = snax.newservice ("foobar", "hello world")
--调用服务中的函数
print(p.req.echo("foobar"))
print(p.pub.touch())
--退出服务
snax.exit(p)
snax.newservice
:这是 snax 框架启动一个 snax 服务的接口,第一个参数是 snax 服务实现脚本的名称,第二个参数才是传入服务中init
方法的启动参数;req
:对应于 snax 服务中的response
pub
:对应于 snax 服务中的subscribe
snax.exit
:结束一个 snax 服务的接口
snax.newservice
会在config
文件中配置的snax
路径上找到"foobar"
模块并加载。由于 skynet 的核心是 C 编写的,所以服务的启动参数只能是一个 字符串。为了更加灵活,snax
在实现时规定了启动服务的消息,newserice
的启动参数是用 lua 协议打包,通过启动消息传递的,也就不受限制了。
其他:
snax
不仅提供了更为简便的创建服务的 API,而且还提供了热更新的接口,随后的内容会做详细的展开和应用举例。
参考:
最新文章
- Selenium2(WebDriver)_如何判断WebElement元素对象是否存在
- Asp.net MVC 数据注解与验证
- C语言面试题(二)
- 今天学习到的关于mysql数据库的linux命令
- 解决Cannot change version of project facet Dynamic web module to 3.0
- POJ1384完全背包问题
- SIP学习之网络链接
- jprofiler安装和配置
- (原创) C# List 找 Max 的 Index
- Git 如何 clone 非 master 分支的代码
- Spring通过SchedulerFactoryBean实现调度任务的配置(定时器)
- (4) MySQL中EXPLAIN执行计划分析
- JAVA基础部分复习(三、泛型)
- 黑马程序员_java基础笔记(10)...JDK1.5的新特性
- Understanding Cache Access
- 拓扑排序(Toposort)
- 基于NABCD评论“欢迎来怼”团队Alpha版作品
- edX MITx: 6.00.1x Introduction to Computer Science and Programming Using Python 课程 Week 1: Python Basics Problem Set 1 Problem 3
- Mahout算法调用展示平台2.1
- org.omg.CORBA.MARSHAL: vmcid: SUN minor code: 211 completed: Maybe
热门文章
- (转)C#自制Web 服务器开发:用C#开发自己的Web服务器
- fatal: refusing to merge unrelated histories的解决方案
- MySQL MERGE存储引擎 简介及用法
- 使用淘宝的npm代理下载模块
- UVA 12657 Boxes in a Line(双向链表+小技巧)
- PyTorch源码解读之torchvision.models(转)
- html-常用块级及行级标签
- SQL 循环 FOR 语句
- [小问题笔记(五)] 用SQL加密字符串(MD5、SHA1),顺便解决读取数据加密后不一样的问题
- Gray Code,求格林码