Skynet 网络消息处理流程/服务器启动流程

网络消息的处理流程

网络消息的监听:由socketdrive.strat(socket)负责监听网络消息
/home/mogu/skynet/skynet/lualib/snax/gateserver.lua ,在此文件中调用。

    function CMD.open( source, conf )
        assert(not socket)
        local address = conf.address or "0.0.0.0"
        local port = assert(conf.port)
        maxclient = conf.maxclient or 1024
        nodelay = conf.nodelay
        skynet.error(string.format("Listen on %s:%d", address, port))
        socket = socketdriver.listen(address, port)
        **socketdriver.start**(socket)
        if handler.open then
            return handler.open(source, conf)
        end
    end

收到客户端的消息的处理
1)在gavaserver中,已经定义了网络消息的处理流程


    local function dispatch_msg(fd, msg, sz)
        if connection[fd] then
            handler.message(fd, msg, sz)
        else
            skynet.error(string.format("Drop message from fd (%d) : %s", fd, netpack.tostring(msg,sz)))
        end
    end

    MSG.data = dispatch_msg

    skynet.register_protocol {
        name = "socket",
        id = skynet.PTYPE_SOCKET,   -- PTYPE_SOCKET = 6
        unpack = function ( msg, sz )
            return netpack.filter( queue, msg, sz)
        end,
        dispatch = function (_, _, q, type, ...)
            queue = q
            print("-=-== type = ", data)
            -- if type == 'more' then assert(false) end
            if type then
                MSG[type](...)
            end
        end
    }

2)在dispatch_msg中调用了handler.message,对消息进行派发。handler.message函数,有gate定义

function handler.message(fd, msg, sz)
    -- recv a package, forward it
    local c = connection[fd]
    local agent = c.agent  -- 由agent服务启动的时候,调用CMD.forward传入。
    if agent then
        skynet.redirect(agent, c.client, "client", 1, msg, sz)
    else
        skynet.send(watchdog, "lua", "socket", "data", fd, netpack.tostring(msg, sz))
    end
end

3)详细看看,c.agent的的来源。c.agent由watchdog中的SOCKET.open中启动agent服务时候传入。

function SOCKET.open(fd, addr)
    skynet.error("New client from : " .. addr)
    agent[fd] = skynet.newservice("agent")
    skynet.call(agent[fd], "lua", "start", { gate = gate, client = fd, watchdog = skynet.self() })
end

4)再看下SOCKET.open的调用者,是由gate中handler.connert调用

function handler.connect(fd, addr)
    local c = {
        fd = fd,
        ip = addr,
    }
    connection[fd] = c
    skynet.send(watchdog, "lua", "socket", "open", fd, addr)
end

5)handler.connect的调用者,是前面提到的gateserver服务中的MSG.open

function MSG.open(fd, msg)
    if client_number >= maxclient then
        socketdriver.close(fd)
            return
        end
        if nodelay then
            socketdriver.nodelay(fd)
        end
        connection[fd] = true
        client_number = client_number + 1
        handler.connect(fd, msg)
    end

最后有很多的问题都指向了gateserver中skynet.register_protocol协议注册。是哪里调用了dispatch。
这个时候,我们可以看看skynet.lua中对skynet.register_protocol的定义。

function skynet.dispatch_message(...)
    local succ, err = pcall(raw_dispatch_message,...)
    while true do
        local key,co = next(fork_queue)
        if co == nil then
            break
        end
        fork_queue[key] = nil
        local fork_succ, fork_err = pcall(suspend,co,coroutine_resume(co))
        if not fork_succ then
            if succ then
                succ = false
                err = tostring(fork_err)
            else
                err = tostring(err) .. "\n" .. tostring(fork_err)
            end
        end
    end
    assert(succ, tostring(err))
end
local debug = require "skynet.debug"
debug.init(skynet, {
    dispatch = skynet.dispatch_message,
    suspend = suspend,
})
skynet.dispatch()这个函数的使用相信小伙伴们都比较熟悉了吧,在skynet中,服务消息的派发都是依靠这个函数的。到了这里,我也很迷糊。。没有搞清楚。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值