skynet luaAPI

skynet.localname(name)

以 . 开头的服务名字

基于Skynet框架开发的服务器是由若干个服务(Service)构成的,可以将Skynet看作是操作系统,服务则可以视为操作系统下的进程。实际上,单个Skynet节点仅仅使用一个操作系统进程,服务之间的通讯是在进程内完成的,所以性能比普通的操作系统进程间通讯要高效。

Skynet框架是使用C语言编写的,所以它的服务也是用C语言开发的。但框架已经提供了一个叫做snlua的服务模块(C语言开发的),snlua通过解析Lua脚本来实现业务逻辑。也就是说,可以在Skynet中启动任意多个snlua服务,只是它们承载的Lua脚本不同。因此,只需要编写文件后缀为.lua的脚本文件,并把文件名作为启动参数,启动snlua即可。

-- 引入Skynet
local skynet = require "skynet"

当引入Skynet时,当前服务不能在Skynet框架之外使用,使用标准的Lua解析器运行包含了Skynet模块的代码时会立即报错,这是因为每个Skynet服务都依赖于一个skynet_context上下文的C对象,上下文对象是 由snlua导入到Lua虚拟机中的。

消息的组成

每个Skynet服务的核心职责是处理其它服务发送过来的消息,并向其它服务发送消息。每个Skynet消息都由5部分构成:

  • session
    大部分消息工作在请求回应模式下,也就是说一个服务向另一个服务发起一个请求,而后收到请求的服务在处理完消息后会回复一条消息。session是由发起请求的服务生成的唯一消息标识。响应方在回应时,会将此session带回。这样发送方才能识别出哪条消息是针对哪一条回应。
    session作为消息的唯一标识,实际上是一个非负整数。当一条消息不需要回复时,按照惯例使用0这个特殊的session号表示。另外,session是由Skynet框架生成并管理,使用者通常并不需要关心太多。

  • source

每个服务都是由一个32位的整数标识的,这个整数可以看作服务在Skynet系统中的地址,也就是消息源。即便是在服务退出后,新启动的服务通常也不会使用已经使用过的地址。除非发生回绕,但一般间隔时间非常长。每条接收到的消息都回携带消息源source,以方便在回应的时候可以指定地址。地址的管理通常是由框架来完成的,所以使用者也无须关心太多。

  • type

消息类别表示每个消息可以接收256种不同类型的消息,每种消息可以有不同的消息编码格式。其中有十来种是框架保留的,通常不建议用户使用。因为用户完全可以利用已有的消息类别,并使用具体的消息内容来区分每条具体消息的含义。框架将这些消息类别映射为字符串以便于记忆。最常用的消息类别为lua,它会广泛的用于Lua编写的服务之间的通讯上。

  • message

message是消息的C指针,在Lua层看来message是一个lightuserdata,不过框架会隐藏这个细节。最终,用户处理的是经过解码后的Lua对象。只有极少数情况下,才需要在Lua层直接操作message这个C指针。

  • size

size表示消息的长度,通常和message一起结合使用。

另外有部分API只在搭建框架时用到,普通服务并不会使用,所以这些API被抽离出来放在skynet.manager模块中。需要时先引入:

require "skynet.manager"

为了兼容老代码,skynet.manager共享skynet命名空间,require "skynet"模块后额外的API依旧存放在skynet空间下,而require "skynet.manager"的返回值同样是skynet命名空间。这些额外的API包括:

  • skynet.launch 启动一个C服务
  • skynet.kill 强行杀死一个服务
  • skynet.abort 退出Skynet进程
  • skynet.register 给自身注册一个名字
  • skynet.name 为一个服务命名
  • skynet.forward_type 将本服务实现为消息转发器,对一类消息进行转发。
  • skynet.filter 过滤消息再处理
  • skynet.monitor 给当前Skynet进程设置一个全局的服务监控

服务地址

每个服务都有一个32位的数字地址,这个地址的高8位表明服务所属的节点。

  • skynet.self() 用于获取当前服务的数字地址
  • skynet.harbor() 用于获取服务所属的节点
  • skynet.address(address) 用于将一个数字地址转换为一个可用于阅读的字符串

同时为了地址使用方便,可以给数字地址起一个字符串的名字。

  • skynet.register(name) 为服务注册一个别名,别名必须不超过16个字符。
  • skynet.name(name, address) 为地址命名,skynet.name(name, skynet.self())skynet.register(name)的功能等价。

服务别名一旦注册,在Skynet系统中是通用的,需要自己约定名字的管理方法。

服务别名一般分为两种类型,使用.开头的名字是在同一个Skynet节点下是有效的,跨节点的Skynet服务对其它节点下的.开头的名字是不可见的。不同的Skynet节点可以定义相同的.开头的名字。

另外以字母开头的名字在整个Skynet网络中都是有效的,可以通过这种全局命名的方式将消息发送到其它节点。原则上不鼓励滥用全局别名,因为它有一定的管理成本。管理的方法是在业务层交换服务的数字地址,让服务自行记住其它服务的地址来传播消息。

skynet.localname(name)用来查询一个以.开头的名字所对应的地址,它是一个非阻塞的API,不可以查询跨节点的全局别名。



作者:JunChow520
链接:https://www.jianshu.com/p/9015bb091151
来源:简书

原文地址:https://www.cnblogs.com/didiaoxiaoguai/p/14467753.html