Explicación del código fuente de IPFS (4)-p2p
importación(
"contexto"
"error"
"tiempo"
net " GX/IPFS/QMPJVXTPVH 8 QJYQDNXNSXF 9KV 9 JEZKD 1 KOZZ 1 HS 3 FCGSNH/Go-Lib P2P-NET "
MANET" GX/qmv 6 FJEMM 1K 8 0X JR VUQ 3 WUVwwou 2 TLDPMN nkrxhzy 3V 6 ai/go-multi addr-net "
ma " GX/ipfs/qmymsdtj 3 hsodkepe 3 eu 3 tscap 2 yvpzj 4 loxnnkde 5 tpt 7/go-multi addr "
pro " GX/ipfs/qmznkthpqfvxs 9 gnbexprfbbxslnyekre 7 jwfm 2 oqhbyqn/go-libp2p-protocol "
p store " GX/ipfs/qmzr 2 xwvvbcbtbgbwnqhwk 2 xcqfar 3 w8 faqpriaaj 7 RSR/go-libp 2p- compañero store "
p2phost " GX/ipfs/qmb 8t 6 ybbsjysvgfrihqlfcjvcezznnesbqbkkyebwdjge/go-libp2p-host "
peer " GX/ipfs/qmdvrmn 1 lhb 4 ybb 8 hmvamlxna 8 xrsewmnk 6 yqxkxotcr vn /go-lib P2P-peer "
)
//La estructura P2P guarda la información de la transmisión/escucha actualmente en ejecución.
//La estructura P2P guarda la información del flujo/escucha que se está ejecutando actualmente
Tipo de estructura P2P {
//Escucha
Registro ListenerRegistry
//Flujo de datos
Registro de transmisión
//ID de nodo
Emparejamiento de identidad. Certificado de identidad
//Dirección de nodo
peerHost p2phost. Host
//Almacén de pares seguro para subprocesos
peerstore pstore. Pierce Stoll
}
//Crear una nueva estructura p2p
// NewP2PCrear una nueva estructura P2P
//Este El nuevo La estructura p2p no contiene los oyentes ni los flujos de datos en la estructura p2p.
func NewP2P(identidad peer.ID, peerHost p2phost.host peerstore pstore.Peerstore) *P2P {
return & ampP2P{
identidad:identidad,
Pilhorst:Pilhorst,
peerstore: peerstore,
}
}
//Crear nuevos datos Método de herramienta de flujo para construir el flujo con ID de nodo, contenido y protocolo.
func (p2p P2P) newStreamTo(ctx2 context. context, p peer. ID, protocolo string) (net. stream, error) {
//se producirá automáticamente después de 30 segundos afuera.
ctx,cancelar:= contexto. ConTimeout(ctx2, time.
Segundos 30) //TODO: ¿Configurable?
DelayCancel()
err := p2p.peerHost.Connect(ctx, pstore.PeerInfo{ID: p})
Si error! = cero {
Devuelve cero, error
}
Devuelve p2p.peerHost.NewStream(ctx2, p, pro. ID (protocolo))
}
//La conversación crea una nueva transmisión P2P para el oyente remoto.
//Crea una nueva transmisión p2p para monitorear la sesión.
// Dial crea una nueva transmisión P2P para el oyente remoto
//Multiaddr es una dirección de Internet multiprotocolo y multiplataforma. Enfatiza la claridad y la autodescripción.
//Recepción interna
func (p2p P2P) dial(ctx context. context, dirección ma. multidirección, peer. ID, cadena prototipo, bindAddr ma. Multiaddr) ( ListenerInfo, error) {
//Obtener información del nodo de la red, host, nulo.
lnet, _, err := manet. DialArgs(bindAddr)
Si se equivoca! =cero{
Devuelve cero, error
}
//Información de monitoreo
listenerInfo := ListenerInfo{
//Identificación del nodo
Identidad: p2p.identity,
///Identificador del protocolo de aplicación.
Protocolo: proto,
}
//Llame a newStreamTo para obtener el nuevo a través del proto ctx (contenido) peer (id de nodo) ( identificador de protocolo) flujo de datos de parámetros.
remoto, err := p2p.newStreamTo(ctx, peer, proto)
Si err! =cero{
Devuelve cero, error
}
//Identificación del protocolo de red
Cambiar lnet {
//La red es "TCP", "TCP 4", "TCP 6".
Caso "tcp", "tcp4", "tcp6":
//Obtener nueva información del oyente nla. oyente, nil
Oyente, err := manet. Escuche(bindAddr)
Si se equivoca! =cero{
si err2 := remoto. restablecer();err2! =cero{
Devuelve cero, error 2
}
Devuelve cero, error
}
/ /Guardar la nueva información obtenida en listeningerInfo.
Información del oyente. dirección = oyente. multiAddress()
listenerInfo. close=oyente
listenerInfo. run=true
//abrir para aceptar
ir a P2P aceptar(& listenerInfo, remoto, oyente)
Predeterminado:
}
return & amplistenerInfo, cero
}
//< /p >
func(P2P * P2P) acepta (información del oyente * información del oyente, transmisión de red remota, manet. del oyente) {
//Cierre el oyente y elimine el controlador de transmisión.
Retrasar al oyente.
close()
//Devuelve conexiones multidireccionales compatibles
//Interfaz con buenas conexiones multidireccionales
local, error:= oyente. aceptar()
si se equivoca! =cero{
Retorno
}
stream := StreamInfo{
//Protocolo de conexión
Protocolo : información del oyente. Protocolo,
//Nodo de ubicación
LocalPeer: listenerInfo. Identidad,
//Dirección del nodo de ubicación
LocalAddr: listenerInfo. Dirección,
//Nodo remoto
RemotePeer: remoto. conectar(). RemotePeer(),
//Dirección del nodo remoto
RemoteAddr: remoto. conectar(). RemoteMultiaddr(),
//Posicionamiento
Local: local,
//Remoto
Remoto: remoto,
//Código de registro
Tabla de registro: & ampp2p. Transmitir,
}
//Registrar información de conexión
p2p. Registrarse (y transmitir)
//Difusión de nodo abierto
stream.startStreaming()
}
//El oyente transmitirá los controladores están envueltos en los oyentes.
//El oyente envuelve el controlador de transmisión en el oyente.
Escriba la interfaz del oyente {
Accept() (net.stream, Error)
Close()Error
}
//P2PListener guarda información sobre el oyente.
// P2PListener contiene información sobre el oyente
Etiqueta de estructura P2PListener
peerHost p2phost. Alojado
Conch Greedy Network. transmitir
proto pro. Identidad
Contexto ctx. Contexto
Cancelar función()
}
//Esperando a que el oyente se conecte.
//Aceptar espera una conexión del oyente
func(il * P2PListener)Accept()(net. stream, error) {
Seleccione {
Caso c:= <-il.conCh:
Devuelve c, cero
Caso <-il.ctx.Done():
return nil, il.ctx.Err()
}
}
//Cierre el oyente y elimine el controlador de transmisión.
// Cerrar cierra el oyente y elimina el controlador de transmisión
func (il *P2PListener) Close() error {
il.cancel() p>
il . peer host . removestreamhandler(il . proto)
Devuelve cero
}
// Listen crea un nuevo P2PListener.
//Listen crea un nuevo P2PListener
func(P2P P2P)registerStreamHandler(CT x2 context. context, protocolo string)(P2PListener, error){
ctx, cancelar: = contexto.
con cancel(ctx2)
List:= & ampP2PListener{
peerHost: p2p.peerHost,
proto: pro. ID (acuerdo),
Concha: hacer (禞网.Stream),
ctx: ctx,
Cancelar: cancelar,
}
P2P . peer host . setstreamhandler(list . proto, func(s net. stream) {
Seleccione {
lista de casos . conch & lt ;- s:
caso<ctx.done():
southreset()
}
})
p>Lista de retorno, cero
}
// NewListener crea un nuevo oyente p2p.
//NewListener crea un nuevo oyente p2p
//Transmisión externa
func (p2p P2P) NewListener(ctx contexto. contexto, cadena prototipo, dirección ma . Multiaddr) (ListenerInfo, error) {
//Llame a RegisterStreamHandler para construir un nuevo oyente.
oyente, err:= P2P.registerstreamhandler(CTX, proto)
Si error! =cero{
Devuelve cero, error
}
//Construye una nueva información de escucha
listenerInfo:= ListenerInfo{ p >
Identidad: p2p.identity,
Protocolo: proto,
Dirección: addr,
Cierre: oyente,
En ejecución: verdadero,
registro:&p2p. Oyentes,
}
vayan a P2P. Aceptar transmisiones(& listenerInfo, oyente)
//Registrar información de conexión
p2p. audiencia. Registrarse(&listenerInfo)
Devolver &listenerInfo, cero
}
//Aceptar transmisión
func(P2P * P2P)aceptar transmisiones( Información del oyente * Información del oyente, oyente Oyente) {
Para listenerInfo. ejecute {
//Un control remoto con una buena conexión remota
, error:= oyente. aceptar()
si se equivoca! =cero{
Oyente. Close()
Roto
}
}
//Cancelar el oyente p2p en el registro
p2p. oyentes .de registrarse(listener info.protocol)
}
// CheckProtoExists comprueba si el controlador de protocolo se ha registrado.
//Manejador multiplex
// CheckProtoExists comprueba si el controlador de protocolo está registrado en
//Manejador multiplex
func(P2P * P2P) comprobar que existe proto (cadena de proto) bool {
protos := p2p.peerHost.Mux().
protocolo()
para _, p := rango de protos {
si p! =Prototipo
Continuar
}
Devuelve verdadero
}
Devuelve falso
}