以太坊的事件框架,存在于目录go-ethereum/event中,它有两种事件框架实现,一种叫TypeMux(go-ethereum/event/event.go,现在已经基本弃用;另外一种叫Feed(go-ethereum/event/feed.go, 它是目前主要使用的对象。取代了前面说的event.go内部的TypeMux。

以太坊的事件框架会把所有的订阅者放到一个集合中,每当事件框架收到某个事件的时候,就把通知所有订阅该事件的所有订阅者。由于TypeMux有可能会阻塞,所以通知订阅者可能会延时很久,估计这就是为什么弃用的原因吧。而Feed基本不会阻塞,一般会及时的把事件通知给订阅者,但需要给每种事件创建一个Feed,订阅或者发送事件则需要在不同的Feed上处理。下面主要介绍一下Feed的实现方式。

Feed是一对多的事件框架。

  • 数据结构

Feed的主要函数以及数据结构如下:
    Subscribe以及Send函数是包外可以调用的函数。

func (f *Feed) Subscribe(channel interface{}) Subscription

Subscribe函数添加一个订阅

func (f *Feed) Send(value interface{}) (nsent int) 

Send函数发送一个订阅事件。

type Feed struct {once      sync.Once        // ensures that init only runs oncesendLock  chan struct{}    // sendLock has a one-element buffer and is empty when held.It protects sendCases.removeSub chan interface{} // interrupts SendsendCases caseList         // the active set of select cases used by Send// The inbox holds newly subscribed channels until they are added to sendCases.mu     sync.Mutexinbox  caseListetype  reflect.Typeclosed bool
}

once保证init函数只执行一次;sendLock是 “Send函数的锁。removeSub是“Send”以及“remove"之间“通讯”接口。sendCases是订阅者列表。inbox是刚刚加入的订阅者列表(Send函数会将inbox的订阅者移动到sendCases中);closed标识此订阅事件的状态。

type feedSub struct {feed    *Feedchannel reflect.ValueerrOnce sync.Onceerr     chan error
}

feedSub是Subscription的一种实现。Feed是管理各种feedSub。

Subscription是个接口,定义在event/subscription.go文件中:
    Subscription提供两个函数:Err函数负责出错处理,Unsubscribe函数停止订阅。

func (sub *feedSub) Unsubscribe() 

Unsubscribe() 实现了订阅者退订某个事件;订阅事件的函数在上边已经实现了。

  • 实现方式

实际运用中,我们主要的流程,就是订阅,发送事件,接收事件,取消订阅。

订阅,订阅时需要一个channel作为参数传入。订阅函数也会校验传入的参数是否为chan以及通道的方向;然后构造一个feedSub数据作为返回值; 使用传入的channel生成了SelectCase,放入inbox,即将新加入的订阅者放入inbox里。

取消订阅,一般注册完成后,订阅者会获取一个Subscription,可以通过它取消订阅和读取通道错误。这时,订阅者会从inbox和sendCases中都被删除。

发布事件,调用Feed.Send(chan x),通过加锁确保本类型事件只有一个发送协程正在进行,然后校验事件类型是否匹配,Feed会尝试给每个订阅者发送事件,如果订阅者阻塞,Feed就继续尝试给下一个订阅者发送,直到给每个订阅者发送事件,返回发送该事件的数量。

接收事件,订阅者通过读取chan里的数据,实现事件的接收。

  • 如何使用

package mainimport ("fmt""sync""github.com/ethereum/go-ethereum/event"
)func main() {type bigevent struct{ number int }var f event.Feedvar wg sync.WaitGroupch := make(chan bitevent)sub := feed.Subscribe(ch)wg.Add(1)go func() {defer wg.Done()for event := range ch {fmt.Printf("Received: %#v\n", event.number)}sub.Unsubscribe()}()feed.Send(bigevent{5})close(ch)wg.Wait()
}

我们设置了事件bigevent,创建了feed,然后订阅feed;开启协程监听通道,看是否有事件推送,等到通多关闭后,取消订阅;

以太坊中的事件机制Feed相关推荐

  1. 区块链开发(十五)以太坊中的Events和Logs解析及用途

    以太坊中的事件(Events)和日志(Logs)是个特别让人困惑的概念,本文帮大家梳理. 因为上篇文章,我们讨论过以太坊go-ethereum客户端查询交易列表的一些办法,这篇文章,我们具体实现一种f ...

  2. ftl有三种映射地址_浅谈以太坊中的三种“树”

    无论是比特币还是以太坊,它们都是完全由代码创造出来的,它们的几乎所有一切都是程序执行的结果.对计算机程序有些了解的朋友应该都知道,计算机程序离不开数据结构和算法. 顺便提一下,有部分人不认为比特币和以 ...

  3. 区块链学习笔记16——以太坊中的交易树和收据树

    十六.以太坊中的交易树和收据树 每次发布一个交易的时候,那些交易会组织成一个交易树,也是一颗Merkle tree跟比特币中的情况是类似的,同时以太坊还增加了一个收据树,每个交易执行完之后会形成一个收 ...

  4. 「前端面试题系列7」Javascript 中的事件机制(从原生到框架)

    前言 这是前端面试题系列的第 7 篇,你可能错过了前面的篇章,可以在这里找到: 理解函数的柯里化 ES6 中箭头函数的用法 this 的原理以及用法 伪类与伪元素的区别及实战 如何实现一个圣杯布局? ...

  5. jQuery中的事件机制深入浅出

    昨天呢,我们大家一起分享了jQuery中的样式选择器,那么今天我们就来看一下jQuery中的事件机制,其实,jQuery中的事件机制与JavaScript中的事件机制区别是不大的,只是,JavaScr ...

  6. [以太坊源代码分析] IV. 椭圆曲线密码学和以太坊中的椭圆曲线数字签名算法应用

    数字签名算法在Ethereum中的应用不少,目前已知至少有两处:一是在生成每个交易(Transaction, tx)对象时,对整个tx对象进行数字签名:二是在共识算法的Clique算法实现中,在针对新 ...

  7. 以太坊中metamask、imtoken等钱包签名的php验证

    以太坊中metamask.imtoken等钱包签名的php验证 之前开发Dapp,需要用到以太坊钱包登陆dapp,找了很久没有这方面的库,加密算法倒是有很多,直接重新写了一个库,https://git ...

  8. 以太坊中的nonce

    以太坊创建每个账户时初始nonce=0,以后每次交易nonce+1,防止以太坊中的replay attack. 参考:https://www.bilibili.com/video/BV1Vt411X7 ...

  9. 敲响OO时代的丧钟——DJ中的事件机制(重写)

    最近一直在思考DJ中的事件机制的设计问题,觉得以前的设计并不够好,关键在于概念还不够清晰,因此语法的设计也不够干净利落.因此我打算重写一遍关于事件机制的语法设定. 事件的本质是在一个系统运行过 ...

  10. 以太坊中的账户、交易、Gas和区块Gas Limit等基本概念

    本篇文章作为科普文章,汇总整理了以太坊中的账户.交易.Gas和区块Gas Limit等相关概念,以便大家在实践中更好的与具体业务相结合. 什么是账户 以太坊账户与我们所知的账户概念有一定相似之处,却又 ...

最新文章

  1. 目标检测中的Tricks
  2. 3项目里面全局用less变量 cli vue_VUE CLI3 less 全局变量引用
  3. 九种破解Xp登录密码方法
  4. 在将varchar值id转换为int时失败_Python—CAN报文转换工具教程
  5. 广工计算机专业离散数学考试题,广工华立2014年离散数学期末考试试题(配答案)...
  6. 『Python』__getattr__()特殊方法
  7. python 字符串格式化语法_Python:字符串格式化
  8. FileZilla 安装配置参考
  9. 【Git】向Gitee提交代码
  10. java默认权限什么时候使用_Java 应用程序默认权限(简例)
  11. 怎么只要小数部分C语言,如何得出一个浮点数的小数部分,要把各个位保存到一个数组里边。...
  12. 端午节那晚,见了个小学时的同学!
  13. Flex(AS) JS抓取HTML页面元素数据
  14. 【springboot】5、lombok
  15. 浅谈安科瑞电能预付费系统在大电力客户中的设计及应用分析
  16. windows cmd 执行命令文件路径带有空格的处理方式
  17. 注册表中设置页面打印参数
  18. 用半角的特殊符号代替全角的特殊符号
  19. 【软件测试】敏捷方法与测试左移
  20. 社会最底层的人,如何突破人生圈层,改变命运?

热门文章

  1. Linux显示2015年日历表
  2. win2003服务器360修复漏洞打不开网页,360浏览器打不开网页,教您怎样解决360浏览器打不开网页...
  3. 亮点前瞻 | 首届 ServerlesssDays · China 大会议程发布
  4. 将多个文件合并为一个文件
  5. 怦然心动(Flipped)-5
  6. Far planner之 障碍物的图搜索
  7. 红蜘蛛显示器测试软件,红蜘蛛5校色仪怎么用?显示器校色及测试色域和色彩精准度详细教程...
  8. 1068 万绿丛中一点红(附逻辑分析,详细注释)
  9. 华为HCNE考试练习题经典模拟题
  10. essay写作要点以及正确的书写格式