千家信息网

HyperLeger Fabric SDK开发(五)——event

发表于:2024-11-15 作者:千家信息网编辑
千家信息网最后更新 2024年11月15日,HyperLeger Fabric SDK开发(五)--event一、event简介1、event简介event包支持访问Fabric网络上的通道事件。事件客户端可以接收区块事件,过滤区块事件,链码事
千家信息网最后更新 2024年11月15日HyperLeger Fabric SDK开发(五)——event

HyperLeger Fabric SDK开发(五)--event

一、event简介

1、event简介

event包支持访问Fabric网络上的通道事件。事件客户端可以接收区块事件,过滤区块事件,链码事件和交易状态事件。
官方文档:
https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/event

2、event使用基本流程

event使用基本流程如下:
A、准备通道客户端上下文
B、创建事件客户端
C、注册事件
D、处理事件(或超时)
E、注销事件
使用示例:

ec, err := New(mockChannelProvider("mychannel"))if err != nil {    fmt.Println("failed to create client")}registration, notifier, err := ec.RegisterChaincodeEvent("examplecc", "event123")if err != nil {    fmt.Println("failed to register chaincode event")}defer ec.Unregister(registration)select {case ccEvent := <-notifier:    fmt.Printf("received chaincode event %v\n", ccEvent)case <-time.After(time.Second * 5):    fmt.Println("timeout while waiting for chaincode event")}// Timeout is expected since there is no event producer// output:// timeout while waiting for chaincode event   

二、event常用接口

1、事件客户端获取

type Client struct {   eventService      fab.EventService   permitBlockEvents bool   fromBlock         uint64   seekType          seek.Type}func New(channelProvider context.ChannelProvider, opts ...ClientOption) (*Client, error)

返回事件客户端实例。客户端接收区块事件,过滤区块事件,链码事件和交易状态事件。
使用示例:

ctx := mockChannelProvider("mychannel")ec, err := New(ctx, WithBlockEvents())if err != nil {    fmt.Println(err)}if ec != nil {    fmt.Println("event client created")} else {    fmt.Println("event client is nil")}// output:// event client created     

2、注册区块事件

func (c *Client) RegisterBlockEvent(filter ...fab.BlockFilter) (fab.Registration, <-chan *fab.BlockEvent, error)
注册块事件。如果调用者没有注册区块事件的权限,则返回错误。不再需要注册时,必须调用取消注册。
参数:
filter是一个可选的过滤器,可过滤掉不需要的事件。只能指定一个过滤器。
返回:注册对象和用于接收事件的通道。调用Unregister时,通道将关闭。
使用示例:

ec, err := New(mockChannelProvider("mychannel"), WithBlockEvents())if err != nil {    fmt.Println("failed to create client")}registration, _, err := ec.RegisterBlockEvent()if err != nil {    fmt.Println("failed to register block event")}defer ec.Unregister(registration)fmt.Println("block event registered successfully")// output:// block event registered successfully

3、注册链码事件

func (c *Client) RegisterChaincodeEvent(ccID, eventFilter string) (fab.Registration, <-chan *fab.CCEvent, error)
注册链代码事件。不再需要注册时,必须调用Unregister。
参数:
ccID是用于接收事件的链码ID
eventFilter是用于接收事件的链码事件过滤器(正则表达式)
返回:注册对象和用于接收事件的通道。 调用取消注册时,通道将关闭。
使用示例:

ec, err := New(mockChannelProvider("mychannel"))if err != nil {    fmt.Println("failed to create client")}registration, _, err := ec.RegisterChaincodeEvent("examplecc", "event123")if err != nil {    fmt.Println("failed to register chaincode event")}defer ec.Unregister(registration)fmt.Println("chaincode event registered successfully")// output:// chaincode event registered successfully

使用示例:

// If you require payload for chaincode events you have to use WithBlockEvents() optionec, err := New(mockChannelProvider("mychannel"), WithBlockEvents())if err != nil {    fmt.Println("failed to create client")}registration, _, err := ec.RegisterChaincodeEvent("examplecc", "event123")if err != nil {    fmt.Println("failed to register chaincode event")}defer ec.Unregister(registration)fmt.Println("chaincode event registered successfully")// output:// chaincode event registered successfully

4、注册过滤区块事件

func (c *Client) RegisterFilteredBlockEvent() (fab.Registration, <-chan *fab.FilteredBlockEvent, error)
注册过滤区块事件。当不再需要注册时,必须调用Unregister。
返回:注册对象和用于接收事件的通道。调用Unregister时,通道将关闭。
使用示例:

ec, err := New(mockChannelProvider("mychannel"))if err != nil {    fmt.Println("failed to create client")}registration, _, err := ec.RegisterFilteredBlockEvent()if err != nil {    fmt.Println("failed to register filtered block event")}defer ec.Unregister(registration)fmt.Println("filtered block event registered successfully")// output:// filtered block event registered successfully

5、注册交易状态事件

func (c *Client) RegisterTxStatusEvent(txID string) (fab.Registration, <-chan *fab.TxStatusEvent, error)
注册交易状态事件。不再需要注册时,必须调用Unregister。
参数:
txID是用于接收事件的交易ID
返回:注册对象和用于接收事件的通道。调用Unregister时,通道将关闭。
使用示例:

ec, err := New(mockChannelProvider("mychannel"))if err != nil {    fmt.Println("failed to create client")}registration, _, err := ec.RegisterTxStatusEvent("tx123")if err != nil {    fmt.Println("failed to register tx status event")}defer ec.Unregister(registration)fmt.Println("tx status event registered successfully")// output:// tx status event registered successfully

6、注销

func (c *Client) Unregister(reg fab.Registration)
删除给定的注册对象并关闭事件通道。
参数:
reg是从其中一个注册函数返回的注册句柄

7、ClientOption选项构建

type ClientOption func(*Client) errorfunc WithBlockEvents() ClientOption

WithBlockEvents指示要接收的区块事件。 注意,调用者必须具有此选项的足够权限。
func WithBlockNum(from uint64) ClientOption
WithBlockNum表示用于接收事件的区块编号。只有deliverclient支持次选项。
func WithSeekType(seek seek.Type) ClientOption
WithSeekType表示所需的搜索类型,最新,最旧或来自给定区块,只有deliverclient支持此项。

三、event示例

var (   sdk           *fabsdk.FabricSDK   channelName   = "assetchannel"   org           = "org1"   user          = "Admin")ctx := sdk.ChannelContext(channelName, fabsdk.WithOrg(org), fabsdk.WithUser(user))cli, err := event.New(ctx)if err != nil {panic(err)}// 区块事件reg, blkevent, err := cli.RegisterBlockEvent()if err != nil {panic(err)}defer cli.Unregister(reg)timeoutctx, cancel := context.WithTimeout(context.Background(), time.Minute)defer cancel()for {    select {    case evt := <-blkevent:    fmt.Printf("received a block", evt)    case <-timeoutctx.Done():    fmt.Println("event timeout, exit!")    return}
0