【skynet】 网络编程之回显服务器

写在前面

skynet 提供了一套 tcp 的 API ,本文将给出简单的回显服务器实现,以及讲解。

文章目录


编译 skynet

拉取 skynet 工程

git clone https://github.com/cloudwu/skynet

编译

make linux

服务框架

agent_mgr

  1. 负责启动 gate 服务
    • "L" 表示客服端的消息前带四字节大端序的 msg_size
    • skynet.address(skynet.self()) 把自己设置为 watchdog ,有新连接通过 text 消息告诉自己
    • port TCP 监听端口
    • 0 将 TCP 数据以默认消息类型传输给 agent
    • 256 最多同时连接 256 个 TCP
  2. 新连接时,启动一个新的 agent 并通知 gate
    • newservice 创建一个 新的 agent
    • forward 通知 gate 把 TCP 数据转发给 agent
    • start 通知 gate 开始接收数据
  3. 客户端关闭连接时,回收资源
    • 关闭 tcp 连接,回收文件描述符
    • 通知 agent 把结束服务

agent

  1. 接收来自 gate 的 TCP 数据,并回写
    • socket.write 向 socket 写入数据
    • skynet.ignoreret 忽略消息返回
  2. 接收来自 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"
相关推荐
_Johnny_15 分钟前
linux 使用SSH密钥配置免密登录
linux·服务器·ssh
哆啦叮当16 分钟前
Linux下root用户共享conda环境给其他用户
linux·运维·服务器·python·conda
Linux猿21 分钟前
828华为云征文 | 云服务器Flexus X实例:部署 Gitea,拥有自己的Git仓库,管理本地代码
服务器·华为云·gitea·云服务器·git仓库·flexus云服务器x实例·华为云服务器
weixin_464838152 小时前
grep命令如何实现正则表达式搜索?
linux·运维·服务器·网络安全·系统架构
桃花岛主704 小时前
Nginx搭建直播服务器,并用rtmp,http-flv,hls三种模式拉流观看直播的流程
运维·服务器·nginx
鲸鱼姐5 小时前
在linux注册服务并开机启动springboot程序
linux·运维·服务器
jyan_敬言5 小时前
虚拟机centos_7 配置教程(镜像源、配置centos、静态ip地址、Finalshell远程操控使用)
linux·运维·服务器·c语言·数据结构·tcp/ip·centos
花花花18 小时前
Linux 文件与目录操作命令详解
linux·运维·服务器·文件·目录·命令
小故渊15 小时前
JSON对象
运维·服务器·json
阳爱铭15 小时前
指标服务平台:全面解析
java·服务器·网络·hadoop·sql·hbase·数据库架构