总体介绍
以太坊内部有大量协程,协程间的调度驱动通过事件机制来完成;具体实现使用
golang的chan机制。主要方案有以下两种。
1.使用观察者模式实现“事件”转发
Feed 类为 observer
-
Subscribe()方法, 客户端调用
开始订阅‘事件’,把客户端的 接收channel 添加到 Feed;同时返回feedSub对象 -
feedSub.Unsubscribe()方法 ,客户端调用
客户端通过调用此方法取消订阅 -
Send(value interface{})方法, Feed(observer) 拥有者调用
通过此方法向所有订阅者发布‘事件’
使用go的chan机制实现通信
- 订阅者把自己的 接收 chan 添加到 Feed(observer)
- Send发布消息时的输入参数也是一个 chan
具体使用示例
1)BlockChain类作为 Feed(observer) 拥有者
- 拥有下面几个 Feed成员
rmLogsFeed event.Feed
chainFeed event.Feed
chainSideFeed event.Feed
chainHeadFeed event.Feed
logsFeed event.Feed - 封装了下面几个订阅函数
SubscribeRemovedLogsEvent
SubscribeChainEvent
SubscribeChainHeadEvent
... - 发布消息时调用 bc.xxxxFeed.Send(ev)
2) TestTransactionGapFilling 作为客户端
- 下行代码定义了事件接收 chan
events := make(chan TxPreEvent, testTxPoolConfig.AccountQueue+5) - 下行代码订阅了tx_pool的事件
sub := pool.txFeed.Subscribe(events) - 通过上面的events接收处理事件
2.全局双工事件通道,根据事件类型订阅和转发
TypeMux 类为observer
- Subscribe()方法, 注册者调用
参数为要接收的‘事件类型’, 返回TypeMuxSubscription对象 - Post()方法, 注册者调用
发送消息,具体实现调用TypeMuxSubscription.deliver() - TypeMuxSubscription. Unsubscribe()方法, 注册者调用
取消订阅 - TypeMuxSubscription.deliver()方法 ,无外部调用
注册者发送消息的具体实现, - TypeMuxSubscription.Chan()方法, 注册者调用
接收事件
以太坊具体使用
-
Ethereum中创建一次,其他地方多次使用 ,全局只有一个对象。
-
Subscribe()和Post()方法在代码中有多次调用,执行对象都来自Ethereum.eventMux指向的对象
网友评论