您的位置:首页 > 其它

skynet服务的本质与缺陷

2015-11-04 17:17 337 查看
skynet是为多人在线游戏打造的轻量级服务端框架,使用c+lua实现。使用这套框架的一个好处就是,基本只需要lua,很少用到c做开发,一定程度上提高了开发效率。但skynet文档也相对较少,所以这里利用一点时间学习和总结skynet相关内容,文章这里就讲解下skynet服务的本质与缺陷,希望能有所帮助。


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,杀掉服务等。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: