风险提示:理性看待区块链,提高风险意识!
golang-event 在以太坊中的使用
首页 > 币界资讯 > 区块链知识 2018-03-18 08:13
摘要
go-ethereum中go-event库的使用github.com/ethereum/go-ethereum/event 包实现了一个事件发布订阅的库,使用接口主要是 event.Feed 类型,以前还有 event.TypeMux 类型,看代码注释,说过时了,目前主要使用 Feed 类型。pac 。
币界网报道:

go-ethereum中go-event库的使用

github.com/ethereum/go-ethereum/event 包实现了一个事件发布订阅的库,使用接口主要是 event.Feed 类型,以前还有 event.TypeMux 类型,看代码注释,说过时了,目前主要使用 Feed 类型。

package main
 import (
 "fmt"
 "sync"
 "github.com/ethereum/go-ethereum/event"
 )
 func main() {
 type someEvent struct{ I int }
 var feed event.Feed
 var wg sync.WaitGroup
 ch := make(chan someEvent)
 sub := feed.Subscribe(ch)
 wg.Add(1)
 go func() {
 defer wg.Done()
 for event := range ch {
 fmt.Printf("Received: %#v\n", event.I)
 }
 sub.Unsubscribe()
 fmt.Println("done")
 }()
 feed.Send(someEvent{5})
 feed.Send(someEvent{10})
 feed.Send(someEvent{7})
 feed.Send(someEvent{14})
 close(ch)
 wg.Wait()
 }

通过调用 event.Feed 类型的Subscrible方法订阅事件通知,需要使用者提前指定接收事件的 channel,Subscribe 返回 Subscription 对象,是一个接口类型:

type Subscription interface {
 Err() // returns the error channel
 Unsubscribe()
 // cancels sending of events, closing the error channel
 }

Err() 返回获取error 的channel,调用Unsubscribe()取消事件订阅。事件的发布者调用 Send() 方法,发送事件。

可以使用同一个channel实例,多次调用Feed 的Subscrible()方法:

package main
 import (
 "fmt"
 "sync"
 "github.com/ethereum/go-ethereum/event"
 )
 func main() {
 var (
 feed event.Feed
 recv sync.WaitGroup
 sender sync.WaitGroup
 )
 ch := make(chan int)
 feed.Subscribe(ch)
 feed.Subscribe(ch)
 feed.Subscribe(ch)
 expectSends := func(value, n int) {
 defer sender.Done()
 if nsent := feed.Send(value); nsent != n {
 fmt.Printf("send delivered %d times, want %d\n", nsent, n)
 }
 }
 expectRecv := func(wantValue, n int) {
 defer recv.Done()
 for v := range ch {
 if v != wantValue {
 fmt.Printf("received %d, want %d\n", v, wantValue)
 } else {
 fmt.Printf("recv v = %d\n", v)
 }
 }
 }
 sender.Add(3)
 for i := 0; i < 3; i++ {
 go expectSends(1, 3)
 }
 go func() {
 sender.Wait()
 close(ch)
 }()
 recv.Add(1)
 go expectRecv(1, 3)
 recv.Wait()
 }

这个例子中, 有三个订阅者, 有三个发送者, 每个发送者发送三次1, 同一个channel ch 里面被推送了9个1。

ethereum event 库还提供了一些高级别的方便接口, 比如event.NewSubscription函数,接收一个函数类型,作为数据的生产者, producer本身在后台一个单独的goroutine内执行, 后台goroutine往用户的channel 发送数据:

package main
 import (
 "fmt"
 "github.com/ethereum/go-ethereum/event"
 )
 func main() {
 ch := make(chan int)
 sub := event.NewSubscription(
 func(quit for i := 0; i < 10; i++ {
 select {
 case ch case <-quit:
 fmt.Println("unsubscribed")
 return nil
 }
 }
 return nil
 })
 for i := range ch {
 fmt.Println(i)
 if i == 4 {
 sub.Unsubscribe()
 break
 }
 }
 }

库也提供了 event.SubscriptionScope 类型用于追踪多个订阅者,提供集中的取消订阅功能:

package main
 import (
 "fmt"
 "sync"
 "github.com/ethereum/go-ethereum/event"
 )
 // This example demonstrates how SubscriptionScope can be used to control the lifetime of
 // subscriptions.
 // Our example program consists of two servers, each of which performs a calculation when
 // requested. The servers also allow subscribing to results of all computations.
 type divServer struct{ results event.Feed }
 type mulServer struct{ results event.Feed }
 func (s *divServer) do(a, b int) int {
 r := a / b
 s.results.Send(r)
 return r
 }
 func (s *mulServer) do(a, b int) int {
 r := a * b
 s.results.Send(r)
 return r
 }
 // The servers are contained in an App. The app controls the servers and exposes them
 // through its API.
 type App struct {
 divServer
 mulServer
 scope event.SubscriptionScope
 }
 func (s *App) Calc(op byte, a, b int) int {
 switch op {
 case '/':
 return s.divServer.do(a, b)
 case '*':
 return s.mulServer.do(a, b)
 default:
 panic("invalid op")
 }
 }
 // The app's SubscribeResults method starts sending calculation results to the given
 // channel. Subscriptions created through this method are tied to the lifetime of the App
 // because they are registered in the scope.
 func (s *App) SubscribeResults(op byte, ch chan switch op {
 case '/':
 return s.scope.Track(s.divServer.results.Subscribe(ch))
 case '*':
 return s.scope.Track(s.mulServer.results.Subscribe(ch))
 default:
 panic("invalid op")
 }
 }
 // Stop stops the App, closing all subscriptions created through SubscribeResults.
 func (s *App) Stop() {
 s.scope.Close()
 }
 func main() {
 var (
 app App
 wg sync.WaitGroup
 divs = make(chan int)
 muls = make(chan int)
 )
 divsub := app.SubscribeResults('/', divs)
 mulsub := app.SubscribeResults('*', muls)
 wg.Add(1)
 go func() {
 defer wg.Done()
 defer fmt.Println("subscriber exited")
 for {
 select {
 case result := <-divs:
 fmt.Println("division happened:", result)
 case result := <-muls:
 fmt.Println("multiplication happened:", result)
 case divErr := <-divsub.Err():
 fmt.Println("divsub.Err() :", divErr)
 return
 case mulErr := <-mulsub.Err():
 fmt.Println("mulsub.Err() :", mulErr)
 return
 }
 }
 }()
 app.Calc('/', 22, 11)
 app.Calc('*', 3, 4)
 app.Stop()
 wg.Wait()
 }

SubscriptionScope的Close() 方法接收 Track 方法的返回值 ,Track 方法负责追踪订阅者。

发表评论
发表评论
暂无评论
    相关阅读
    柴犬(SHIB)在 2025 年和2030年会涨多高?能否实现1美分目标?
    区块链
    2025-01-08 11:31:45
    未来一年可以说是最难以预测的一年。地缘政治错综复杂、美国监管政策不确定。尽管美国股市似乎无法停止上涨,利率也只能下降,但我们知道,这两件事都不是板上钉钉的事。
    区块链
    2025-01-08 11:31:18
    周一,比特币和以太坊 ETF 共计流入 11 亿美元,在现货基金年初出现 3.2 亿美元流入后,形成了积极的势头。
    比特币
    2025-01-08 10:31:17
    Ripple宣布已集成Chainlink,为用户提供实时RLUSD定价数据,增强了稳定币在DeFi上的实用性和访问权限。DeFi开发人员还可以将RLUSD支持集成到他们的应用程序中,用于贷款和交易等多种用例。
    区块链
    2025-01-08 10:03:08
    莱特币在看涨突破后一周内上涨12%——282美元的目标现在就在眼前!
    区块链
    2025-01-08 09:41:19
    推荐专栏
    热门币种
    更多
    币种
    美元价格
    24H涨跌幅
    BTC比特币
    60,963.61 USDT
    ¥435,103.38
    -2.72%
    ETH以太坊
    3,368.69 USDT
    ¥24,042.67
    -0.3%
    BNB币安币
    570.68 USDT
    ¥4,073.00
    -0.28%
    USDT泰达币
    1.02 USDT
    ¥7.25
    -0.19%
    SOL
    135.96 USDT
    ¥970.36
    +7.66%
    USDC
    1.00 USDT
    ¥7.15
    -0.01%
    TON
    7.59 USDT
    ¥54.14
    +4.55%
    XRP瑞波币
    0.47720 USDT
    ¥3.41
    +0.48%
    DOGE狗狗币
    0.12210 USDT
    ¥0.87140
    +2.43%
    ADA艾达币
    0.39050 USDT
    ¥2.79
    +3.88%
    热搜币种
    更多
    币种
    美元价格
    24H涨跌幅
    狗狗币
    0.3541 USDT
    ¥2.59
    -9.65%
    Filecoin
    5.3381 USDT
    ¥39.11
    -10.48%
    比特币
    96512.03 USDT
    ¥707,090.56
    -5.13%
    Gatechain Token
    17.9689 USDT
    ¥131.65
    -2.85%
    Horizen
    23.2652 USDT
    ¥170.45
    -17.39%
    dYdX
    1.4038 USDT
    ¥10.28
    -13.8%
    Solana
    198.71 USDT
    ¥1,455.84
    -8.68%
    柚子
    0.814 USDT
    ¥5.96
    -10.6%
    Shiba Inu
    2.174E-5 USDT
    ¥0.00
    -9.45%
    艾达币
    0.998 USDT
    ¥7.31
    -8.29%
    FTX Token
    2.9131 USDT
    ¥21.34
    -13.97%
    火币积分
    0.9291 USDT
    ¥6.81
    -29.01%
    最新快讯
    更多
    WEEX交易所WE-Launch上线Violet,投入WXT瓜分3100万枚VIOLET代币
    2025-01-08 12:00:34
    美国现货比特币ETF昨日净流入5346万美元
    2025-01-08 12:00:02
    昨日美国比特币现货ETF净流入5348万美元
    2025-01-08 11:59:02
    CertiKAlert:7天前部署的IPC代币存在漏洞,黑客通过闪电贷保护机制盗取约59万美元
    2025-01-08 11:58:42
    IREN:2024全年比特币挖矿产出达3984枚BTC
    2025-01-08 11:57:41
    昨日贝莱德IBIT净流入5.9718亿美元,交易量达31亿美元
    2025-01-08 11:54:57
    IPC代币疑遭攻击,损失约59万美元
    2025-01-08 11:53:10