兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端.docx
- 文档编号:4414902
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:17
- 大小:19.68KB
兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端.docx
《兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端.docx》由会员分享,可在线阅读,更多相关《兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端.docx(17页珍藏版)》请在冰豆网上搜索。
兄弟连区块链技术培训Fabric10源代码分析16gossip流言算法#GossipServerGossip服务端
兄弟连区块链技术培训Fabric1.0源代码分析(16)gossip(流言算法)#GossipServer(Gossip服务端)
##1、GossipServer概述
GossipServer相关代码,分布在protos/gossip、gossip/comm目录下。
目录结构如下:
* protos/gossip目录:
* message.pb.go,GossipClient接口定义及实现,GossipServer接口定义。
* gossip/comm目录:
* comm.go,Comm接口定义。
* conn.go,connFactory接口定义,以及connectionStore结构体及方法。
* comm_impl.go,commImpl结构体及方法(同时实现GossipServer接口/Comm接口/connFactory接口)。
* demux.go,ChannelDeMultiplexer结构体及方法。
##2、GossipClient接口定义及实现
###2.1、GossipClient接口定义
```go
type GossipClient interface {
//GossipStreamisthegRPCstreamusedforsendingandreceivingmessages
GossipStream(ctxcontext.Context,opts...grpc.CallOption)(Gossip_GossipStreamClient, error)
//Pingisusedtoprobearemotepeer'saliveness
Ping(ctxcontext.Context,in*Empty,opts...grpc.CallOption)(*Empty, error)
}
//代码在protos/gossip/message.pb.go
```
###2.2、GossipClient接口实现
```go
type gossipClient struct {
cc*grpc.ClientConn
}
func NewGossipClient(cc*grpc.ClientConn)GossipClient{
return &gossipClient{cc}
}
func (c*gossipClient)GossipStream(ctxcontext.Context,opts...grpc.CallOption)(Gossip_GossipStreamClient, error){
stream,err:
=grpc.NewClientStream(ctx,&_Gossip_serviceDesc.Streams[0],c.cc, "/gossip.Gossip/GossipStream",opts...)
if err!
= nil {
return nil,err
}
x:
=&gossipGossipStreamClient{stream}
return x, nil
}
func (c*gossipClient)Ping(ctxcontext.Context,in*Empty,opts...grpc.CallOption)(*Empty, error){
out:
= new(Empty)
err:
=grpc.Invoke(ctx, "/gossip.Gossip/Ping",in,out,c.cc,opts...)
if err!
= nil {
return nil,err
}
return out, nil
}
//代码在protos/gossip/message.pb.go
```
###2.3、Gossip_GossipStreamClient接口定义及实现
```go
type Gossip_GossipStreamClient interface {
Send(*Envelope) error
Recv()(*Envelope, error)
grpc.ClientStream
}
type gossipGossipStreamClient struct {
grpc.ClientStream
}
func (x*gossipGossipStreamClient)Send(m*Envelope) error {
return x.ClientStream.SendMsg(m)
}
func (x*gossipGossipStreamClient)Recv()(*Envelope, error){
m:
= new(Envelope)
if err:
=x.ClientStream.RecvMsg(m);err!
= nil {
return nil,err
}
return m, nil
}
//代码在protos/gossip/message.pb.go
```
##3、GossipServer接口定义
###3.1、GossipServer接口定义
```go
type GossipServer interface {
//GossipStreamisthegRPCstreamusedforsendingandreceivingmessages
GossipStream(Gossip_GossipStreamServer) error
//Pingisusedtoprobearemotepeer'saliveness
Ping(context.Context,*Empty)(*Empty, error)
}
func RegisterGossipServer(s*grpc.Server,srvGossipServer){
s.RegisterService(&_Gossip_serviceDesc,srv)
}
func _Gossip_GossipStream_Handler(srv interface{},streamgrpc.ServerStream) error {
return srv.(GossipServer).GossipStream(&gossipGossipStreamServer{stream})
}
func _Gossip_Ping_Handler(srv interface{},ctxcontext.Context,dec func(interface{}) error,interceptorgrpc.UnaryServerInterceptor)(interface{}, error){
in:
= new(Empty)
if err:
=dec(in);err!
= nil {
return nil,err
}
if interceptor== nil {
return srv.(GossipServer).Ping(ctx,in)
}
info:
=&grpc.UnaryServerInfo{
Server:
srv,
FullMethod:
"/gossip.Gossip/Ping",
}
handler:
= func(ctxcontext.Context,req interface{})(interface{}, error){
return srv.(GossipServer).Ping(ctx,req.(*Empty))
}
return interceptor(ctx,in,info,handler)
}
var _Gossip_serviceDesc=grpc.ServiceDesc{
ServiceName:
"gossip.Gossip",
HandlerType:
(*GossipServer)(nil),
Methods:
[]grpc.MethodDesc{
{
MethodName:
"Ping",
Handler:
_Gossip_Ping_Handler,
},
},
Streams:
[]grpc.StreamDesc{
{
StreamName:
"GossipStream",
Handler:
_Gossip_GossipStream_Handler,
ServerStreams:
true,
ClientStreams:
true,
},
},
Metadata:
"gossip/message.proto",
}
//代码在protos/gossip/message.pb.go
```
###3.2、Gossip_GossipStreamServer接口定义及实现
```go
type Gossip_GossipStreamServer interface {
Send(*Envelope) error
Recv()(*Envelope, error)
grpc.ServerStream
}
type gossipGossipStreamServer struct {
grpc.ServerStream
}
func (x*gossipGossipStreamServer)Send(m*Envelope) error {
return x.ServerStream.SendMsg(m)
}
func (x*gossipGossipStreamServer)Recv()(*Envelope, error){
m:
= new(Envelope)
if err:
=x.ServerStream.RecvMsg(m);err!
= nil {
return nil,err
}
return m, nil
}
//代码在protos/gossip/message.pb.go
```
##4、Comm接口/connFactory接口定义
###4.1、Comm接口定义
```go
type Comm interface {
//返回此实例的PKIid
GetPKIid()common.PKIidType
//向节点发送消息
Send(msg*proto.SignedGossipMessage,peers...*RemotePeer)
//探测远程节点是否有响应
Probe(peer*RemotePeer) error
//握手验证远程节点
Handshake(peer*RemotePeer)(api.PeerIdentityType, error)
Accept(common.MessageAcceptor)<-chan proto.ReceivedMessage
//获取怀疑脱机节点的只读通道
PresumedDead()<-chan common.PKIidType
//关闭到某个节点的连接
CloseConn(peer*RemotePeer)
//关闭
Stop()
}
//代码在gossip/comm/comm.go
```
###4.2、connFactory接口定义
```go
type connFactory interface {
createConnection(endpoint string,pkiIDcommon.PKIidType)(*connection, error)
}
//代码在gossip/comm/conn.go
```
##5、commImpl结构体及方法(同时实现GossipServer接口/Comm接口/connFactory接口)
###5.1、commImpl结构体定义
```go
type commImpl struct {
selfCertHash[]byte
peerIdentityapi.PeerIdentityType
idMapperidentity.Mapper
logger*logging.Logger
opts[]grpc.DialOption
secureDialOpts func()[]grpc.DialOption
connStore*connectionStore
PKIID[]byte
deadEndpoints chan common.PKIidType
msgPublisher*ChannelDeMultiplexer
lock*sync.RWMutex
lsnrnet.Listener
gSrv*grpc.Server
exitChan chan struct{}
stopWGsync.WaitGroup
subscriptions[]chan proto.ReceivedMessage
port int
stopping int32
}
//代码在gossip/comm/comm_impl.go
```
###5.2、commImpl结构体方法
```go
//conn.serviceConnection(),启动连接服务
func (c*commImpl)GossipStream(streamproto.Gossip_GossipStreamServer) error
//return&proto.Empty{}
func (c*commImpl)Ping(context.Context,*proto.Empty)(*proto.Empty, error)
func (c*commImpl)GetPKIid()common.PKIidType
//向指定节点发送消息
func (c*commImpl)Send(msg*proto.SignedGossipMessage,peers...*RemotePeer)
//探测远程节点是否有响应,_,err=cl.Ping(context.Background(),&proto.Empty{})
func (c*commImpl)Probe(remotePeer*RemotePeer) error
//握手验证远程节点,_,err=cl.Ping(context.Background(),&proto.Empty{})
func (c*commImpl)Handshake(remotePeer*RemotePeer)(api.PeerIdentityType, error)
func (c*commImpl)Accept(acceptorcommon.MessageAcceptor)<-chan proto.ReceivedMessage
func (c*commImpl)PresumedDead()<-chan common.PKIidType
func (c*commImpl)CloseConn(peer*RemotePeer)
func (c*commImpl)Stop()
//创建并启动gRPCServer,以及注册GossipServer实例
func NewCommInstanceWithServer(port int,idMapperidentity.Mapper,peerIdentityapi.PeerIdentityType,
//将GossipServer实例注册至peerServer
func NewCommInstance(s*grpc.Server,cert*tls.Certificate,idStoreidentity.Mapper,
func extractRemoteAddress(streamstream) string
func readWithTimeout(stream interface{},timeouttime.Duration,address string)(*proto.SignedGossipMessage, error)
//创建gRPCServer,grpc.NewServer(serverOpts...)
func createGRPCLayer(port int)(*grpc.Server,net.Listener,api.PeerSecureDialOpts,[]byte)
//创建与服务端连接
func (c*commImpl)createConnection(endpoint string,expectedPKIIDcommon.PKIidType)(*connection, error)
//向指定节点发送消息
func (c*commImpl)sendToEndpoint(peer*RemotePeer,msg*proto.SignedGossipMessage)
//returnatomic.LoadInt32(&c.stopping)==int32
(1)
func (c*commImpl)isStopping() bool
func (c*commImpl)emptySubscriptions()
func (c*commImpl)authenticateRemotePeer(streamstream)(*proto.ConnectionInfo, error)
func (c*commImpl)disconnect(pkiIDcommon.PKIidType)
func (c*commImpl)createConnectionMsg(pkiIDcommon.PKIidType,certHash[]byte,certapi.PeerIdentityType,signerproto.Signer)(*proto.SignedGossipMessage, error)
//代码在gossip/comm/comm_impl.go
```
####5.2.1、funcNewCommInstanceWithServer(portint,idMapperidentity.Mapper,peerIdentityapi.PeerIdentityType,secureDialOptsapi.PeerSecureDialOpts,dialOpts...grpc.DialOption)(Comm,error)
创建并启动gRPCServer,以及注册GossipServer实例
```go
func NewCommInstanceWithServer(port int,idMapperidentity.Mapper,peerIdentityapi.PeerIdentityType,
secureDialOptsapi.PeerSecureDialOpts,dialOpts...grpc.DialOption)(Comm, error){
var llnet.Listener
var s*grpc.Server
var certHash[]byte
if len(dialOpts)== 0 {
//peer.gossip.dialTimeout,gRPC连接拨号的超时
dialOpts=[]grpc.DialOption{grpc.WithTimeout(util.GetDurationOrDefault("peer.gossip.dialTimeout",defDialTimeout))}
}
if port> 0 {
//创建gRPCServer,grpc.NewServer(serverOpts...)
s,ll,secureDialOpts,certHash=createGRPCLayer(port)
}
commInst:
=&commImpl{
selfCertHash:
certHash,
PKIID:
idMapper.GetPKIidOfCert(peerIdentity),
idMapper:
idMapper,
logger:
util.GetLogger(util.LoggingCommModule,fmt.Sprintf("%d",port)),
peerIdentity:
peerIdentity,
opts:
dialOpts,
secureDialOpts:
secureDialOpts,
port:
port,
lsnr:
ll,
gSrv:
s,
msgPublisher:
NewChannelDemultiplexer(),
lock:
&sync.RWMutex{},
deadEndpoints:
make(chan common.PKIidType, 100),
stopping:
int32(0),
exitChan:
make(chan struct{}, 1),
subscriptions:
make([]chan proto.ReceivedMessage, 0),
}
commInst.connStore=newConnStore(commInst,commInst.logger)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端 兄弟连 区块 技术培
链接地址:https://www.bdocx.com/doc/4414902.html