RPCAgent.lua 3.4 KB
Newer Older
baidwwy's avatar
baidwwy 已提交
1 2 3 4
-- @Author              : GGELUA
-- @Last Modified by    : baidwwy
-- @Date                : 2022-03-07 18:52:00
-- @Last Modified time  : 2022-05-14 10:13:39
baidwwy's avatar
lua  
baidwwy 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

local adler32 = require('zlib').adler32
local m_pack = require('cmsgpack').pack
local m_unpack = require('cmsgpack.safe').unpack

local c_isyieldable = coroutine.isyieldable
local c_runing = coroutine.running
local c_yield = coroutine.yield
local c_resume = coroutine.resume
local c_create = coroutine.create
local t_unpack = table.unpack
local PackAgent = require('HPSocket.PackAgent')
local RPCAgent = class('RPCAgent', PackAgent)

local _REG = setmetatable({}, {__mode = 'k'})
local _CBK = setmetatable({}, {__mode = 'k'})

function RPCAgent:RPCAgent()
    PackAgent.PackAgent(self) --初始化父类
    local reg = {}
    _REG[self] = reg --private
    _CBK[self] = {} --private
baidwwy's avatar
baidwwy 已提交
27
    self.REG = {}
baidwwy's avatar
lua  
baidwwy 已提交
28
    return setmetatable(
baidwwy's avatar
baidwwy 已提交
29
        self.REG,
baidwwy's avatar
lua  
baidwwy 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
        {
            __newindex = function(t, k, v)
                if type(v) == 'function' then
                    reg[k] = v
                    reg[adler32(k)] = v
                end
            end,
            __index = reg
        }
    )
end

function RPCAgent:__index(k) --调用方法
    local co, main = c_runing()
    local funp = type(k) == 'string' and adler32(k) or k
    if co and not main and c_isyieldable() then --如果有协程,则有返回值
        return function(self, id, ...)
            if id then
                local cop = adler32(tostring(co))
                _CBK[self][cop] = co
                self._hp:Send(id, m_pack {funp, cop, ...})
                return c_yield()
            end
        end
    end
    return function(self, id, ...)
        if id then
            self._hp:Send(id, m_pack {funp, 0, ...})
        end
    end
end

function RPCAgent:发送(id, ...)
    return self._hp:Send(id, m_pack {...})
end

local function cofunc(self, id, cop, func, ...)
    self._hp:Send(id, m_pack {0, cop, func(self, id, ...)})
end

function RPCAgent:_接收事件(id, data)
    if rawget(self, '接收事件') then
        self:接收事件(id, data)
        return
    end

    local t = m_unpack(data)
    if type(t) == 'table' then
        local funp, cop = t[1], t[2]
        if funp == 0 then --返回
            local co = _CBK[self][cop]
            if co then
                _CBK[self][cop] = nil
                coroutine.xpcall(co, t_unpack(t, 3))
            end
        else
            local func = _REG[self][funp]
            if func then
                if cop == 0 then --没有返回
                    func(self, id, t_unpack(t, 3))
                else
                    local r = coroutine.xpcall(cofunc, self, id, cop, func, t_unpack(t, 3))
                    if r == coroutine.FALSE then
                        self._hp:Send(id, m_pack {0, cop, nil})
                    end
                end
            elseif rawget(self, 'RPC事件') then --未注册的函数
                func = self.RPC事件
                if cop == 0 then --没有返回
                    func(self, id, funp, t_unpack(t, 3))
                else
                    local r = coroutine.xpcall(cofunc, self, id, cop, func, funp, t_unpack(t, 3))
                    if r == coroutine.FALSE then
                        self._hp:Send(id, m_pack {0, cop, nil})
                    end
                end
            elseif co ~= 0 then
                self._hp:Send(id, m_pack {0, cop, nil})
            end
        end
    end
end

return RPCAgent