写在前面
skynet 提供了一套 tcp 的 API ,本文将给出简单的回显服务器实现,以及讲解。
文章目录
编译 skynet
拉取 skynet 工程
git clone https://github.com/cloudwu/skynet
        编译
make linux
        服务框架
agent_mgr
- 负责启动 gate 服务
"L"表示客服端的消息前带四字节大端序的 msg_sizeskynet.address(skynet.self())把自己设置为 watchdog ,有新连接通过 text 消息告诉自己portTCP 监听端口0将 TCP 数据以默认消息类型传输给agent256最多同时连接 256 个 TCP
 - 新连接时,启动一个新的 
agent并通知 gatenewservice创建一个 新的agentforward通知 gate 把 TCP 数据转发给agentstart通知 gate 开始接收数据
 - 客户端关闭连接时,回收资源
- 关闭 tcp 连接,回收文件描述符
 - 通知 
agent把结束服务 
 
agent
- 接收来自 gate 的 TCP 数据,并回写
socket.write向 socket 写入数据skynet.ignoreret忽略消息返回
 - 接收来自 agent_mgr 的指令,并执行
 
注意事项
skynet.write 和 skynet.close 中的 id 并非 linux 中的 fd 。
源代码
agent_mgr 服务
            
            
              lua
              
              
            
          
          -- agent_mgr.lua
local skynet = require "skynet"
local socket = require "skynet.socket"
local queue = require "skynet.queue"
require "skynet.manager"
local cs = queue()
local connections = {}
local CMD = {
    open = function (source, session, _)
        local agent = skynet.newservice("agent")
        connections[session] = { session = session, agent = agent }
        skynet.send(source, "text", "forward", session, skynet.address(agent), skynet.address(source))
        skynet.send(source, "text", "start", session)
    end,
    close = function(_, session, _)
        skynet.error("socket close:", session)
        socket.close_fd(session)
        local connection = connections[session]
        connections[session] = nil
        skynet.send(connection.agent, "lua", "exit")
    end,
}
function init()
    skynet.register_protocol({
        name = "text",
        id = skynet.PTYPE_TEXT,
        pack = function (...)
            local n = select("#" , ...)
            if n == 0 then
                return ""
            elseif n == 1 then
                return tostring(...)
            else
                return table.concat({...}," ")
            end
        end,
        unpack = skynet.tostring,
        dispatch = function (_, source, message)
            local session, cmd, parm = string.match(message, "(%d+) (%w+) ?(.*)")
            local f = assert(CMD[cmd], cmd)
            cs(f, source, tonumber(session), parm)
        end
    })
end
skynet.init(init)
skynet.start(function()
    local port = 8000
    local gate = skynet.launch("gate", "L", skynet.address(skynet.self()), port, 0, 256)
    assert(gate, string.format("launch zinc_gate on port %s fail", port))
end)
        agent 服务
            
            
              lua
              
              
            
          
          -- agent.lua
local skynet = require "skynet"
local socket = require "skynet.socket"
local queue = require "skynet.queue"
require "skynet.manager"
local cs = queue()
function init()
    skynet.register_protocol({
        name = "client",
        id = skynet.PTYPE_CLIENT,
        pack = skynet.tostring,
        unpack = skynet.tostring,
        dispatch = function(session, source, message)
            cs(function()
                socket.write(session, message)
                skynet.ignoreret()
                skynet.error("session:", session, "source:", source, "message:", message)
            end)
        end,
    })
    skynet.dispatch("lua", function(_, _, cmd, ...)
        local args = ...
        cs(function()
            local f = skynet[cmd]
            f(args)
        end)
    end)
end
skynet.init(init)
skynet.start(function()
end)
        配置文件
            
            
              lua
              
              
            
          
          -- config.echo
-- 启动多少个工作线程
thread = 8
-- skynet 工作在单节点模式下
harbor = 0
-- skynet 节点的主程序
start = "agent_mgr"
-- lua 服务所在的位置
luaservice = "./service/?.lua"
cservice = "./cservice/?.so"