skynet服务的本质与缺陷
2015-11-04 17:17
337 查看
skynet是为多人在线游戏打造的轻量级服务端框架,使用c+lua实现。使用这套框架的一个好处就是,基本只需要lua,很少用到c做开发,一定程度上提高了开发效率。但skynet文档也相对较少,所以这里利用一点时间学习和总结skynet相关内容,文章这里就讲解下skynet服务的本质与缺陷,希望能有所帮助。
或许我们对skynet服务有着太多的疑问:
skynet服务究竟是什么,为什么有人说服务是一个lua虚拟机,服务与服务之间的通讯是怎样的,为什么服务的内存高居不下, 为什么拿skynet服务和erlang进程做比较?等等。。。而这一切的答案都在代码里面,让我们一步一步解开她的面纱。
先从skynet服务创建的接口说起,方式如下:
[plain] view
plaincopy
skynet.newservice(name, ...)
看下这个函数的实现:
[plain] view
plaincopy
-- skynet.lua
function skynet.newservice(name, ...)
return skynet.call(".launcher", "lua" , "LAUNCH", "snlua", name, ...)
end
实际上是调用另外一个服务(.launcher)完成skynet服务的创建。看下launcher服务的处理:
[plain] view
plaincopy
-- launcher.lua
-- 处理服务的创建
local function launch_service(service, ...)
local param = table.concat({...}, " ")
local inst = skynet.launch(service, param)
local response = skynet.response()
if inst then
services[inst] = service .. " " .. param
instance[inst] = response
else
response(false)
return
end
return inst
end
-- 处理 LAUNCH 类消息
function command.LAUNCH(_, service, ...)
launch_service(service, ...)
return NORET
end
-- 处理launcher服务接收到的消息
skynet.dispatch("lua", function(session, address, cmd , ...)
cmd = string.upper(cmd)
local f = command[cmd]
if f then
local ret = f(address, ...)
if ret ~= NORET then
skynet.ret(skynet.pack(ret))
end
else
skynet.ret(skynet.pack {"Unknown command"} )
end
end)
也就是调用 skynet.launch(service, param),实际上 .launcher 服务也是通过这函数实现的。
[plain] view
plaincopy
-- bootstrap.lua
local launcher = assert(skynet.launch("snlua","launcher"))
skynet.name(".launcher", launcher)
为什么要通过另外一个服务创建新的服务?主要目的是为了方便管理所有服务,比如统计,gc,杀掉服务等。
skynet服务的本质
或许我们对skynet服务有着太多的疑问:skynet服务究竟是什么,为什么有人说服务是一个lua虚拟机,服务与服务之间的通讯是怎样的,为什么服务的内存高居不下, 为什么拿skynet服务和erlang进程做比较?等等。。。而这一切的答案都在代码里面,让我们一步一步解开她的面纱。
服务创建API
先从skynet服务创建的接口说起,方式如下:[plain] view
plaincopy
skynet.newservice(name, ...)
看下这个函数的实现:
[plain] view
plaincopy
-- skynet.lua
function skynet.newservice(name, ...)
return skynet.call(".launcher", "lua" , "LAUNCH", "snlua", name, ...)
end
实际上是调用另外一个服务(.launcher)完成skynet服务的创建。看下launcher服务的处理:
[plain] view
plaincopy
-- launcher.lua
-- 处理服务的创建
local function launch_service(service, ...)
local param = table.concat({...}, " ")
local inst = skynet.launch(service, param)
local response = skynet.response()
if inst then
services[inst] = service .. " " .. param
instance[inst] = response
else
response(false)
return
end
return inst
end
-- 处理 LAUNCH 类消息
function command.LAUNCH(_, service, ...)
launch_service(service, ...)
return NORET
end
-- 处理launcher服务接收到的消息
skynet.dispatch("lua", function(session, address, cmd , ...)
cmd = string.upper(cmd)
local f = command[cmd]
if f then
local ret = f(address, ...)
if ret ~= NORET then
skynet.ret(skynet.pack(ret))
end
else
skynet.ret(skynet.pack {"Unknown command"} )
end
end)
也就是调用 skynet.launch(service, param),实际上 .launcher 服务也是通过这函数实现的。
[plain] view
plaincopy
-- bootstrap.lua
local launcher = assert(skynet.launch("snlua","launcher"))
skynet.name(".launcher", launcher)
为什么要通过另外一个服务创建新的服务?主要目的是为了方便管理所有服务,比如统计,gc,杀掉服务等。
相关文章推荐
- 集成支付宝的相关问题
- Android ScroolView不能撑满全屏的问题
- Exception sending context initialized event to listener instance of class org.emp.utils.InitDataList
- JDK动态代理实现简单AOP--转
- xcode 升级插件失效问题
- 我的博客今天开通了,请多指教!
- [转] Maven镜像配置
- TCP/IP协议原理与应用笔记18:构成子网和超网
- ReactMotion Demo8 分析
- python下运行报"SyntaxError: Non-ASCII character '/xe6' "错误解决方法
- js,window.重定向页面
- 分布式消息队列kafka系列介绍 — 核心API介绍及实例
- 正则表达式--操作字符串a
- 图片轮播添加点击事件遇到的问题
- HDU-3555-数位DP-Bomb
- java下16进制字符串和字节数组的相互转化
- 九度OJ剑指offer中关于顺时针输出矩阵的问题分析
- cache 的设计与实现--转载
- ALLEGRO 问题累积
- Android webView打不开网页的解决办法