boost signal机制:
boost的signal/slots用来实现event事件机制,一个signal可以connect多个slots,当发送signal的时候,所有连接的slot会触发注册的回调函数,主要的API如下:
connect(): arg1是注册的回调函数,如图的slotx,arg2是触发回调的顺序。
operator():signal的emit发送接口,触发connect注册的回调函数。
在EOS中将该机制做了进一步的封装,封装为channel和method。所有的method和channel都可以从plugin_interface.hpp 文件中找到。下面简单介绍这两种机制:
method:
plugin提供的方法调用接口
如上图,method继承了method_caller,method_caller实现了对signal的 operator()的封装,method的成员函数register_provider则封装了signal的connect()方法。
method 对外的接口是宏method_decl,如:
其中chain_plugin_interface是tag,没有具体意义,signed_block_ptr(unit32 blocknum)是boost::signal成员函数 operator()的入参类型。如果想实例化method,使用methods::get_block_by_number::method_type
例如实例化为_get_block_by_number,则发送信号就可以使用operator(),如_get_block_by_number(arg…),这个实际上调用的是method继承的method_caller的operator(),也是boost signal的operator(),即发送signal触发register_provider注册的回调函数。
综上,method留下的接口就是method_decl(用来封装signal)和 register_provider(用来封装connect 注册回调函数)
channel:
plugin提供的消息交互的通道,抽象出了下面几个概念:
channel:消息通道
handle:消息处理句柄,封装了connection
subscribe:注册消息处理句柄
signal:消息
emit:消息发送器,封装了signal的 operator()
从上面的类图可以看到,channel 组合了signal,使用subscribe封装了回调注册函数connect(),使用handle封装了connection,用于保存注册的回调函数,除此之外还组合了boost::asio::io_service 的异步IO处理库,使用publish封装了post(), 作用只是将入参传递给boost::signal的operator(), 用于触发消息的handle句柄。
但是,发送消息分为两部分,controller使用emit(signal), 而plugin则使用publish,接收消息的处理也分为两部分,一部分是使用channel&&subscribe&&handle的方式,另一部分是使用boost原生的boost::signal&&connect &&connection方式,这部分比较混乱。
网友评论