Fabric 1.0原始碼分析(38) Peer #BroadcastClient(Broadcast客戶端)

尹成發表於2018-05-20
# 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

相關文章