Fabric 1.0源代码分析(38) Peer #BroadcastClient(Broadcast客户端)

# Fabric 1.0源代码笔记 之 Peer #BroadcastClient(Broadcast客户端)

## 1、BroadcastClient概述

BroadcastClient代码分布如下:

* peer/common/ordererclient.go,BroadcastClient接口定义及实现,及BroadcastClient工具函数。
* protos/orderer/ab.pb.go,AtomicBroadcastClient接口定义及实现,AtomicBroadcast_BroadcastClient接口定义及实现。

## 2、BroadcastClient接口定义及实现

### 2.1、BroadcastClient工具函数

```go
//构造broadcastClient
func GetBroadcastClient(orderingEndpoint string, tlsEnabled bool, caFile string) (BroadcastClient, error)
//代码在peer/common/ordererclient.go
```

代码如下:

```go
func GetBroadcastClient(orderingEndpoint string, tlsEnabled bool, caFile string) (BroadcastClient, error) {
    var opts []grpc.DialOption
    if tlsEnabled { //检查TLS
        if caFile != "" {
            creds, err := credentials.NewClientTLSFromFile(caFile, "")
            opts = append(opts, grpc.WithTransportCredentials(creds))
        }
    } else {
        opts = append(opts, grpc.WithInsecure())
    }

    opts = append(opts, grpc.WithTimeout(3*time.Second))
    opts = append(opts, grpc.WithBlock())

    conn, err := grpc.Dial(orderingEndpoint, opts...)
    //NewAtomicBroadcastClient构造atomicBroadcastClient
    //.Broadcast构造atomicBroadcastBroadcastClient
    client, err := ab.NewAtomicBroadcastClient(conn).Broadcast(context.TODO())
    return &broadcastClient{conn: conn, client: client}, nil
}

//代码在peer/common/ordererclient.go
```

### 2.2、BroadcastClient接口定义及实现

```go
type BroadcastClient interface {
    //Send data to orderer
    Send(env *cb.Envelope) error
    Close() error
}

type broadcastClient struct {
    conn *grpc.ClientConn
    client ab.AtomicBroadcast_BroadcastClient
}

//获取应答
func (s *broadcastClient) getAck() error {
    msg, err := s.client.Recv()
    if msg.Status != cb.Status_SUCCESS {
        //是否成功
    }
    return nil
}

//向orderer发送数据
func (s *broadcastClient) Send(env *cb.Envelope) error {
    err := s.client.Send(env) //发送cb.Envelope
    err := s.getAck() //获取应答
    return err
}

func (s *broadcastClient) Close() error { //关闭连接
    return s.conn.Close()
}

//代码在peer/common/ordererclient.go
```

## 3、AtomicBroadcastClient接口定义及实现

### 3.1、AtomicBroadcastClient工具函数

```go
//构造atomicBroadcastClient
func NewAtomicBroadcastClient(cc *grpc.ClientConn) AtomicBroadcastClient {
    return &atomicBroadcastClient{cc}
}
//代码在protos/orderer/ab.pb.go
```

### 3.2、AtomicBroadcastClient接口定义

```go
type AtomicBroadcastClient interface {
    //广播
    Broadcast(ctx context.Context, opts ...grpc.CallOption) (AtomicBroadcast_BroadcastClient, error)
    //投递
    Deliver(ctx context.Context, opts ...grpc.CallOption) (AtomicBroadcast_DeliverClient, error)
}
//代码在protos/orderer/ab.pb.go
```

### 3.3、AtomicBroadcastClient接口实现

AtomicBroadcastClient接口实现,即atomicBroadcastClient结构体及方法。

```go
type atomicBroadcastClient struct {
    cc *grpc.ClientConn
}

//构造atomicBroadcastBroadcastClient
func (c *atomicBroadcastClient) Broadcast(ctx context.Context, opts ...grpc.CallOption) (AtomicBroadcast_BroadcastClient, error) {
    stream, err := grpc.NewClientStream(ctx, &_AtomicBroadcast_serviceDesc.Streams[0], c.cc, "/orderer.AtomicBroadcast/Broadcast", opts...)
    x := &atomicBroadcastBroadcastClient{stream}
}
func (c *atomicBroadcastClient) Deliver(ctx context.Context, opts ...grpc.CallOption) (AtomicBroadcast_DeliverClient, error) {
    stream, err := grpc.NewClientStream(ctx, &_AtomicBroadcast_serviceDesc.Streams[1], c.cc, "/orderer.AtomicBroadcast/Deliver", opts...)
    x := &atomicBroadcastDeliverClient{stream}
}

var _AtomicBroadcast_serviceDesc = grpc.ServiceDesc{
    ServiceName: "orderer.AtomicBroadcast",
    HandlerType: (*AtomicBroadcastServer)(nil),
    Methods: []grpc.MethodDesc{},
    Streams: []grpc.StreamDesc{
        {
            StreamName: "Broadcast",
            Handler: _AtomicBroadcast_Broadcast_Handler,
            ServerStreams: true,
            ClientStreams: true,
        },
        {
            StreamName: "Deliver",
            Handler: _AtomicBroadcast_Deliver_Handler,
            ServerStreams: true,
            ClientStreams: true,
        },
    },
    Metadata: "orderer/ab.proto",
}
//代码在protos/orderer/ab.pb.go
```

### 3.4、atomicBroadcastBroadcastClient

```go
type AtomicBroadcast_BroadcastClient interface {
    Send(*common.Envelope) error //发送
    Recv() (*BroadcastResponse, error) //接收
    grpc.ClientStream
}

type atomicBroadcastBroadcastClient struct {
    grpc.ClientStream
}

func (x *atomicBroadcastBroadcastClient) Send(m *common.Envelope) error {
    return x.ClientStream.SendMsg(m)
}

func (x *atomicBroadcastBroadcastClient) Recv() (*BroadcastResponse, error) {
    m := new(BroadcastResponse)
    if err := x.ClientStream.RecvMsg(m); err != nil {
        return nil, err
    }
    return m, nil
}
//代码在protos/orderer/ab.pb.go
```

### 3.5、atomicBroadcastDeliverClient

```go
type AtomicBroadcast_DeliverClient interface {
    Send(*common.Envelope) error //发送
    Recv() (*DeliverResponse, error) //接收
    grpc.ClientStream
}

type atomicBroadcastDeliverClient struct {
    grpc.ClientStream
}

func (x *atomicBroadcastDeliverClient) Send(m *common.Envelope) error {
    return x.ClientStream.SendMsg(m)
}

func (x *atomicBroadcastDeliverClient) Recv() (*DeliverResponse, error) {
    m := new(DeliverResponse)
    if err := x.ClientStream.RecvMsg(m); err != nil {
        return nil, err
    }
    return m, nil
}
//代码在protos/orderer/ab.pb.go
```






网址:http://www.qukuailianxueyuan.io/



欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:CSDN

尹成学院微信:备注:CSDN




网址:http://www.qukuailianxueyuan.io/



欲领取造币技术与全套虚拟机资料

区块链技术交流QQ群:756146052  备注:CSDN

尹成学院微信:备注:CSDN

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值