兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端Word下载.docx
《兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端Word下载.docx》由会员分享,可在线阅读,更多相关《兄弟连区块链技术培训Fabric 10源代码分析16gossip流言算法 #GossipServerGossip服务端Word下载.docx(17页珍藏版)》请在冰豆网上搜索。
```
###2.2、GossipClient接口实现
gossipClient
struct
cc*grpc.ClientConn
func
NewGossipClient(cc*grpc.ClientConn)GossipClient{
return
&
gossipClient{cc}
(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
nil,err
x:
=&
gossipGossipStreamClient{stream}
x,
nil
(c*gossipClient)Ping(ctxcontext.Context,in*Empty,opts...grpc.CallOption)(*Empty,
out:
new(Empty)
err:
=grpc.Invoke(ctx,
/gossip.Gossip/Ping"
in,out,c.cc,opts...)
out,
###2.3、Gossip_GossipStreamClient接口定义及实现
Gossip_GossipStreamClient
Send(*Envelope)
error
Recv()(*Envelope,
grpc.ClientStream
gossipGossipStreamClient
(x*gossipGossipStreamClient)Send(m*Envelope)
error
x.ClientStream.SendMsg(m)
(x*gossipGossipStreamClient)Recv()(*Envelope,
m:
new(Envelope)
=x.ClientStream.RecvMsg(m);
err!
m,
##3、GossipServer接口定义
###3.1、GossipServer接口定义
GossipServer
GossipStream(Gossip_GossipStreamServer)
Ping(context.Context,*Empty)(*Empty,
RegisterGossipServer(s*grpc.Server,srvGossipServer){
s.RegisterService(&
_Gossip_serviceDesc,srv)
_Gossip_GossipStream_Handler(srv
interface{},streamgrpc.ServerStream)
srv.(GossipServer).GossipStream(&
gossipGossipStreamServer{stream})
_Gossip_Ping_Handler(srv
interface{},ctxcontext.Context,dec
func(interface{})
error,interceptorgrpc.UnaryServerInterceptor)(interface{},
in:
=dec(in);
interceptor==
srv.(GossipServer).Ping(ctx,in)
info:
grpc.UnaryServerInfo{
Server:
srv,
FullMethod:
handler:
func(ctxcontext.Context,req
interface{})(interface{},
srv.(GossipServer).Ping(ctx,req.(*Empty))
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"
_Gossip_GossipStream_Handler,
ServerStreams:
true,
ClientStreams:
Metadata:
gossip/message.proto"
###3.2、Gossip_GossipStreamServer接口定义及实现
Gossip_GossipStreamServer
grpc.ServerStream
gossipGossipStreamServer
(x*gossipGossipStreamServer)Send(m*Envelope)
x.ServerStream.SendMsg(m)
(x*gossipGossipStreamServer)Recv()(*Envelope,
=x.ServerStream.RecvMsg(m);
##4、Comm接口/connFactory接口定义
###4.1、Comm接口定义
Comm
//返回此实例的PKIid
GetPKIid()common.PKIidType
//向节点发送消息
Send(msg*proto.SignedGossipMessage,peers...*RemotePeer)
//探测远程节点是否有响应
Probe(peer*RemotePeer)
//握手验证远程节点
Handshake(peer*RemotePeer)(api.PeerIdentityType,
Accept(common.MessageAcceptor)<
-chan
proto.ReceivedMessage
//获取怀疑脱机节点的只读通道
PresumedDead()<
common.PKIidType
//关闭到某个节点的连接
CloseConn(peer*RemotePeer)
//关闭
Stop()
//代码在gossip/comm/comm.go
###4.2、connFactory接口定义
connFactory
createConnection(endpoint
string,pkiIDcommon.PKIidType)(*connection,
//代码在gossip/comm/conn.go
##5、commImpl结构体及方法(同时实现GossipServer接口/Comm接口/connFactory接口)
###5.1、commImpl结构体定义
commImpl
selfCertHash[]byte
peerIdentityapi.PeerIdentityType
idMapperidentity.Mapper
logger*logging.Logger
opts[]grpc.DialOption
secureDialOpts
func()[]grpc.DialOption
connStore*connectionStore
PKIID[]byte
deadEndpoints
chan
msgPublisher*ChannelDeMultiplexer
lock*sync.RWMutex
lsnrnet.Listener
gSrv*grpc.Server
exitChan
struct{}
stopWGsync.WaitGroup
subscriptions[]chan
port
int
stopping
int32
//代码在gossip/comm/comm_impl.go
###5.2、commImpl结构体方法
//conn.serviceConnection(),启动连接服务
(c*commImpl)GossipStream(streamproto.Gossip_GossipStreamServer)
//return&
proto.Empty{}
(c*commImpl)Ping(context.Context,*proto.Empty)(*proto.Empty,
(c*commImpl)GetPKIid()common.PKIidType
//向指定节点发送消息
(c*commImpl)Send(msg*proto.SignedGossipMessage,peers...*RemotePeer)
//探测远程节点是否有响应,_,err=cl.Ping(context.Background(),&
proto.Empty{})
(c*commImpl)Probe(remotePeer*RemotePeer)
//握手验证远程节点,_,err=cl.Ping(context.Background(),&
(c*commImpl)Handshake(remotePeer*RemotePeer)(api.PeerIdentityType,
(c*commImpl)Accept(acceptorcommon.MessageAcceptor)<
(c*commImpl)PresumedDead()<
(c*commImpl)CloseConn(peer*RemotePeer)
(c*commImpl)Stop()
//创建并启动gRPCServer,以及注册GossipServer实例
NewCommInstanceWithServer(port
int,idMapperidentity.Mapper,peerIdentityapi.PeerIdentityType,
//将GossipServer实例注册至peerServer
NewCommInstance(s*grpc.Server,cert*tls.Certificate,idStoreidentity.Mapper,
extractRemoteAddress(streamstream)
string
readWithTimeout(stream
interface{},timeouttime.Duration,address
string)(*proto.SignedGossipMessage,
//创建gRPCServer,grpc.NewServer(serverOpts...)
createGRPCLayer(port
int)(*grpc.Server,net.Listener,api.PeerSecureDialOpts,[]byte)
//创建与服务端连接
(c*commImpl)createConnection(endpoint
string,expectedPKIIDcommon.PKIidType)(*connection,
(c*commImpl)sendToEndpoint(peer*RemotePeer,msg*proto.SignedGossipMessage)
//returnatomic.LoadInt32(&
c.stopping)==int32
(1)
(c*commImpl)isStopping()
bool
(c*commImpl)emptySubscriptions()
(c*commImpl)authenticateRemotePeer(streamstream)(*proto.ConnectionInfo,
(c*commImpl)disconnect(pkiIDcommon.PKIidType)
(c*commImpl)createConnectionMsg(pkiIDcommon.PKIidType,certHash[]byte,certapi.PeerIdentityType,signerproto.Signer)(*proto.SignedGossipMessage,
####5.2.1、funcNewCommInstanceWithServer(portint,idMapperidentity.Mapper,peerIdentityapi.PeerIdentityType,secureDialOptsapi.PeerSecureDialOpts,dialOpts...grpc.DialOption)(Comm,error)
创建并启动gRPCServer,以及注册GossipServer实例
secureDialOptsapi.PeerSecureDialOpts,dialOpts...grpc.DialOption)(Comm,
llnet.Listener
s*grpc.Server
certHash[]byte
len(dialOpts)==
0
//peer.gossip.dialTimeout,gRPC连接拨号的超时
dialOpts=[]grpc.DialOption{grpc.WithTimeout(util.GetDurationOrDefault("
peer.gossip.dialTimeout"
defDialTimeout))}
port>
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:
struct{},
1),
subscriptions:
make([]chan
proto.ReceivedMessage,
0),
commInst.connStore=newConnStore(commInst,commInst.logger)