网关开发6.lua绑定委托(delegate)实现多播调用

Posted 平安与喜乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网关开发6.lua绑定委托(delegate)实现多播调用相关的知识,希望对你有一定的参考价值。

背景

在程序开发过程中有时会遇到事件流的问题,某一个结果会触发A、B、C等一系列动作。需要将各种事件注册给委托类(Delegate)。Delegate类会依次触发注册的函数,完成相应的动作。

实现原理

lua中可以使用元表和队列的形式进行实现

实现细节

delegate.lua

local _M =  

local _MT =  __index = _M 

local setmetatable = setmetatable
local table_remove = table.remove

-- _invoke_list 注册队列
-- _count 注册计数
function _M.new()
    return setmetatable( _invoke_list =  , _count = 0 , _MT)
end
-- __call 函数实现
function _MT:__call(...)
    local _invoke_list = self._invoke_list
    for i = 1, self._count do
        _invoke_list[i](...)
    end
end
-- 增加
local function add_delegate(self, cb, ...)
    if not cb then
        return self
    end
    local _invoke_list = self._invoke_list
    local idx = self._count + 1
    self._invoke_list[idx] = cb
    self._count = idx
    return add_delegate(self, ...)  -- 递归添加
end

-- 会检查是否已经注册
local function add_delegate2(self, cb, ...)
    if not cb then
        return self
    end
    local _invoke_list = self._invoke_list
    for i = 1, self._count do
        if _invoke_list[i] == cb then
            -- already exists, skip
            return add_delegate2(self, ...)
        end
    end
    local _invoke_list = self._invoke_list
    local idx = self._count + 1
    self._invoke_list[idx] = cb
    self._count = idx
    return add_delegate2(self, ...)
end

local function remove_delegate(self, cb, ...)
    if not cb then
        return self
    end
    local _invoke_list = self._invoke_list
    for i = 1, self._count do
        if _invoke_list[i] == cb then
            table_remove(_invoke_list, i)
            self._count = self._count - 1
            break
        end
    end
    return remove_delegate(self, ...)
end

local function is_empty(self)
    return self._count == 0
end

_M.__add = add_delegate
_M.__sub = remove_delegate
_M.invoke = _MT.__call
_M.add_delegate = add_delegate
_M.add_delegate2 = add_delegate2
_M.remove_delegate = remove_delegate
_M.is_empty = is_empty

return _M

应用

-- 测试函数
local function delegate_test1(data)
    ngx.log(ngx.INFO,"delegate_test1 "..data)
end
local function delegate_test2(data)
    ngx.log(ngx.INFO,"delegate_test2 ".. data)
end

local function init() 
    watcher  = delegate.new()
    watcher:add_delegate2(delegate_test1)
    watcher:add_delegate2(delegate_test2)
    watcher("test")
end

测试

思考与总结

整个实现就是一个简单列表和对列表的操作,很好理解。结合场景实现一些广播功会更加方便。

以上是关于网关开发6.lua绑定委托(delegate)实现多播调用的主要内容,如果未能解决你的问题,请参考以下文章

关于jquery的事件委托-bind,live,delegate,on的区别发展

jQuery事件绑定和委托实例

jQuery事件绑定.on()简要概述及应用

c#winform 多线程绑定datagridview会造成假死,滚动条无法滚动,用委托怎么做

jQuery事件绑定.on()简要概述及应用

关于js模拟c#的Delegate(委托)实现