WEB3DEV

Cover image for libp2p-pubsub Descoberta de Pares com Kademlia DHT
AIengineer13
AIengineer13

Posted on • Atualizado em

libp2p-pubsub Descoberta de Pares com Kademlia DHT

Sumário

  1. libp2p gossipsub
  2. Contexto
  3. Descoberta de pares libp2p
  4. Estruturação
  5. Kademlia DHT
  6. Descoberta de Pares
  7. Subiscritor gossipsub
  8. Executar aplicativo
  9. instalar dependências golang
  10. Referências

libp2p gossipsub

There was no time to think

Contexto

No meu post anterior, discuti sobre a construção de um sistema de publicador/assinante (pubsub) ponto a ponto com libp2-pubsub. A implementação feita com gossipsub do go-libp2p-pubsub livraria. A principal preocupação que tive com essa aplicação é que ela não pode descobrir os pares por trás do NAT. Isso significa que ele não pode se conectar aos pares por trás do NAT. Por exemplo, se eu executar um par pubsub na minha máquina local e outro na nuvem AWS. As mensagens do gossipsub não são entregues entre esses pares. A razão  é multicast DNS[mDNS] algoritmo de descoberta de pares que usei. Para superar esse problema de descoberta de pares, podemos usar a abordagem baseada na Tabela de Hash Distribuída ([DHT]. Neste post vou discutir sobre a descoberta de pares libp2p-pubsub com DHT. Todos os códigos-fonte relacionados a este post estão disponíveis em gitlab. Por favor copie este repositório e continue com o post.

Descoberta de pares libp2p  

 Depois de criar um host, como os hosts vão descobrir uns aos outros? Existem duas opções disponíveis na libp2p: DNS multicast (mDNS) e uma Tabela de Hash Distribuída.(mDNS)

envia um multicast UDP  mensagem na porta 5353, anunciando sua presença. Isso é usado, por exemplo, pelo Apple Bonjour ou por impressoras. Funciona em redes locais, mas é claro que não funciona na internet.Um DHT pode ser usado para descobrir pares  também. Quando um par se junta a um DHT, ele pode usar o armazenamento de valor-chave para anunciar sua presença e encontrar outros pares na rede. A chave usada para anunciar sua presença é chamada de ponto de encontro.  

Existem duas diferenças principais entre usar mDNS ou um DHT para descobrir pares. O primeiro que já mencionei, mDNS não funciona na internet, onde um DHT funciona. A segunda diferença é que um DHT requer nós de inicialização. Outros nós podem ingressar na rede conectando-se a um nó de inicialização e, em seguida, descobrir o restante da rede.  

Estruturação

Eu usei a biblioteca libp2p-pubsub para construir o Librumchain que é um armazenamento blockchain leve e altamente escalável. Em Librumchain existe um grupo de consenso central que roda em nós baseados em nuvem com consenso Proof-of-Authority. Os nós de borda projetados para serem executados em nós leves baseados em Raspberry-Pi. O grupo de consenso principal gera blocos e os armazena no IPFS-Cluster(IPFS-Cluster foi usado como armazenamento de blocos). As informações de bloco geradas (por exemplo, o hash IPFS do bloco) serão publicadas nos nós de borda Raspberry-Pi via libp2p gossipsub. A figura a seguir descreve a arquitetura do Librumchain com Grupo de consenso central, IPFS-Cluster e nós de borda Raspberry-Pi.

Arquitetura do Librumchain

Em meu post anterior, desenvolvi este aplicativo com libp2p gossipsub usando o método de descoberta de pares mDNS. Só funcionava em rede local e não funcionava com os pares na internet pública. Então eu incorporei o método de descoberta de pares DHT para resolver esse problema. No aplicativo pubsub, o par do publicador recebe mensagens da linha de comando e as envia para um tópico chamado librum. Em seguida, os assinantes desse tópico do librum recebem os dados via gossipsub ponto a ponto. Os pares descobrem outros pares na rede usando o método DHT. Assim, pode funcionar pela internet. Esta é uma versão simplificada do sistema pubsub do Librumchain.

lIBRUM TOPIC

Kademlia DHT

libp2p DHT usa Kademlia DHT. No programa a seguir, criei pares de inicialização registrados no Kademlia DHT no DHT. Uma coisa importante a notar aqui está na linha 17-18. Adicionou uma opção para instruir o par que, caso nenhum par de inicialização seja fornecido, ele deve entrar no modo servidor. No modo servidor, ele atua como um nó de inicialização, permitindo que outros pares se juntem a ele. Às vezes, você pode precisar habilitar o UPnP na configuração do roteador para que isso funcione. Caso você queira se juntar ao Kademlia DHT global da libp2p, você pode usar os pares de inicialização em dht.DefaultBootstrapPeers.

  

package main

import (
    "context"
    "log"
    "sync"

    "github.com/libp2p/go-libp2p-core/host"
    "github.com/libp2p/go-libp2p-core/peer"
    "github.com/libp2p/go-libp2p-kad-dht"
    "github.com/multiformats/go-multiaddr"
)

func NewDHT(ctx context.Context, host host.Host, bootstrapPeers []multiaddr.Multiaddr) (*dht.IpfsDHT, error) {
    var options []dht.Option

    // se não houver pares de bootstrap, este par age como um nó de bootstrap
    // outros pares podem usar este endereço ipfs de par dht

    if len(bootstrapPeers) == 0 {
        options = append(options, dht.Mode(dht.ModeServer))
    }

    kdht, err := dht.New(ctx, host, options...)
    if err != nil {
        return nil, err
    }

    if err = kdht.Bootstrap(ctx); err != nil {
        return nil, err
    }

    var wg sync.WaitGroup
    for _, peerAddr := range bootstrapPeers {
        peerinfo, _ := peer.AddrInfoFromP2pAddr(peerAddr)

        wg.Add(1)
        go func() {
            defer wg.Done()
            if err := host.Connect(ctx, *peerinfo); err != nil {
                log.Printf("Error while connecting to node %q: %-v", peerinfo, err)
            } else {
                log.Printf("Connection established with bootstrap node: %q", *peerinfo)
            }
        }()
    }
    wg.Wait()

    return kdht, nil
}
I3.97KL0LDI1.76KwhoissourceRank8.43MPIN0Summary reportDiagnosisDensity00n/a
Enter fullscreen mode Exit fullscreen mode

Descoberta de Pares

Então eu criei outro programa para descobrir os pares na rede usando o protocolo de descoberta de pares DHT e rendezvous criado anteriormente. O protocolo Rendezvous destina-se a fornecer um mecanismo leve para descoberta generalizada de pares. Ele pode ser usado para fins de inicialização, descoberta de pares em tempo real, roteamento específico do aplicativo e assim por diante. Qualquer nó que implemente o protocolo de rendezvous pode atuar como um ponto de encontro, permitindo a descoberta de pares relevantes de forma descentralizada.

Aqui, a função FindPeers() fornece todos os pares que foram descobertos no ponto de encontro. Como o próprio nó também faz parte dos pares descobertos, ele precisa ser filtrado. Para todos os outros pares , verifique se eles já estão conectados, caso contrário, disque-os para criar uma conexão.





package main



import (



"context"



"fmt"



"log"



"time"



"github.com/libp2p/go-libp2p-core/host"



"github.com/libp2p/go-libp2p-core/network"



"github.com/libp2p/go-libp2p-discovery"



dht "github.com/libp2p/go-libp2p-kad-dht"



)



func Discover(ctx context.Context, h host.Host, dht *dht.IpfsDHT, rendezvous string) {



var routingDiscovery = discovery.NewRoutingDiscovery(dht)



discovery.Advertise(ctx, routingDiscovery, rendezvous)



ticker := time.NewTicker(time.Second * 1)



defer ticker.Stop()



for {



select {



case <-ctx.Done():



return



case <-ticker.C:



peers, err := discovery.FindPeers(ctx, routingDiscovery, rendezvous)



if err != nil {



log.Fatal(err)



}



for _, p := range peers {



if p.ID == h.ID() {



continue



}



if h.Network().Connectedness(p.ID) != network.Connected {



_, err = h.Network().DialPeer(ctx, p.ID)



fmt.Printf("Connected to peer %s\n", p.ID.Pretty())



if err != nil {



continue



}



}



}



}



}



}

Enter fullscreen mode Exit fullscreen mode

Publicador Gossipsub

Existem dois tipos de pares de publicador na rede, pares  de inicialização (pares públicos) e pares normais (pares por trás do NAT). Como mencionei acima, as funções de inicialização do DHT adicionam uma opção para instruir o par a agir como um nó de inicialização, permitindo que outros pares se juntem a ele. Para manter as coisas simples, criei esses dois publicadores em programas separados (você pode criá-lo facilmente em um único programa). Um publicador criou uma lista de inicialização vazia, então ela atua como um par de inicialização. Outro criado com o endereço IPFS do par de inicialização. A seguir está a implementação golang dos publicadores. Eu adicionei comentários para descrever a função de cada linha no código. O Publicador recebe mensagens ouvindo a linha de comando e publica no tópico.

  




package main



import (



"bufio"



"context"



"fmt"



"os"



"time"



"github.com/libp2p/go-libp2p"



"github.com/libp2p/go-libp2p-core/host"



"github.com/libp2p/go-libp2p-core/peer"



pubsub "github.com/libp2p/go-libp2p-pubsub"



"github.com/libp2p/go-libp2p/p2p/discovery/mdns"



"github.com/multiformats/go-multiaddr"



)



// DiscoveryInterval é a frequência com que re-publicamos nossos registros mDNS.

const DiscoveryInterval = time.Hour



// DiscoveryServiceTag é usado em nossos anúncios mDNS para descobrir outros pares.



const DiscoveryServiceTag = "librum-pubsub"



func main() {



ctx := context.Background()



 // Cria um novo Host libp2p que escuta em uma porta TCP aleatória



// Podemos especificar uma porta como /ip4/0.0.0.0/tcp/3326

// we can specify port like /ip4/0.0.0.0/tcp/3326



host, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"))



if err != nil {



panic(err)



}



// ver os detalhes do host  e do endereço



fmt.Printf("host ID %s\n", host.ID().Pretty())



fmt.Printf("following are the assigned addresses\n")



for _, addr := range host.Addrs() {



fmt.Printf("%s\n", addr.String())



}



fmt.Printf("\n")



// cria um novo serviço PubSub usando o roteador GossipSub



gossipSub, err := pubsub.NewGossipSub(ctx, host)



if err != nil {



panic(err)



}



// Configura o DHT com pares de descoberta vazios

// então este será um pares  de descoberta para outros



// Este par deve ser executado na nuvem (com endereço ip público)



discoveryPeers := []multiaddr.Multiaddr{}



dht, err := NewDHT(ctx, host, discoveryPeers)



if err != nil {



panic(err)



}



// Configura a descoberta de pares



go Discover(ctx, host, dht, "librum")



// setup local mDNS discovery



// Configura a descoberta de mDNS local



if err := setupDiscovery(host); err != nil {



panic(err)



}

// junta ao tópico pubsub chamado librum

room := "librum"



topic, err := gossipSub.Join(room)



if err != nil {



panic(err)



}



// Cria o publicador(editor)



publish(ctx, topic)



}



// start publisher to topic



// inicia o editor no tópico



func publish(ctx context.Context, topic *pubsub.Topic) {



for {



scanner := bufio.NewScanner(os.Stdin)



for scanner.Scan() {



fmt.Printf("enter message to publish: \n")



msg := scanner.Text()



if len(msg) != 0 {




// Publica a mensagem no tópico



bytes := []byte(msg)



topic.Publish(ctx, bytes)



}



}



}



}





//  O discoveryNotifee é notificado quando encontrado um novo par via descoberta de mDNS




type discoveryNotifee struct {



h host.Host



}



// HandlePeerFound se conecta a pares descobertos via mDNS. Assim que estiverem conectados,



// o sistema PubSub começará a interagir automaticamente com eles se eles também



 // suportam PubSub.



func (n *discoveryNotifee) HandlePeerFound(pi peer.AddrInfo) {



fmt.Printf("discovered new peer %s\n", pi.ID.Pretty())



err := n.h.Connect(context.Background(), pi)



if err != nil {



fmt.Printf("error connecting to peer %s: %s\n", pi.ID.Pretty(), err)



}



}



// setupDiscovery cria um serviço de descoberta mDNS e o anexa ao Host libp2p.



// Isso nos permite descobrir automaticamente pares na mesma LAN e nos conectar a eles.



func setupDiscovery(h host.Host) error {



// Configura a descoberta de mDNS para encontrar pares locais



s := mdns.NewMdnsService(h, DiscoveryServiceTag, &discoveryNotifee{h: h})



return s.Start()



}








Enter fullscreen mode Exit fullscreen mode


  






package main



import (



"bufio"



"context"



"fmt"



"os"



"time"



"github.com/libp2p/go-libp2p"



"github.com/libp2p/go-libp2p-core/host"



"github.com/libp2p/go-libp2p-core/peer"



pubsub "github.com/libp2p/go-libp2p-pubsub"



"github.com/libp2p/go-libp2p/p2p/discovery/mdns"



"github.com/multiformats/go-multiaddr"



)



// DiscoveryInterval é a frequência com que re-publicamos nossos registros mDNS.

const DiscoveryInterval = time.Hour



// DiscoveryServiceTag é usado em nossos anúncios mDNS para descobrir outros pares.



const DiscoveryServiceTag = "librum-pubsub"



func main() {



ctx := context.Background()



 // Cria um novo Host libp2p que escuta em uma porta TCP aleatória



// Podemos especificar uma porta como /ip4/0.0.0.0/tcp/3326

// we can specify port like /ip4/0.0.0.0/tcp/3326



host, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"))



if err != nil {



panic(err)



}



// ver os detalhes do host  e do endereço



fmt.Printf("host ID %s\n", host.ID().Pretty())



fmt.Printf("following are the assigned addresses\n")



for _, addr := range host.Addrs() {



fmt.Printf("%s\n", addr.String())



}



fmt.Printf("\n")



// cria um novo serviço PubSub usando o roteador GossipSub



gossipSub, err := pubsub.NewGossipSub(ctx, host)



if err != nil {



panic(err)



}



// Configura o DHT com pares de descoberta vazios

// então este será um pares  de descoberta para outros



// Este par deve ser executado na nuvem (com endereço ip público)



discoveryPeers := []multiaddr.Multiaddr{}



dht, err := NewDHT(ctx, host, discoveryPeers)



if err != nil {



panic(err)



}



// Configura a descoberta de pares



go Discover(ctx, host, dht, "librum")



// setup local mDNS discovery



// Configura a descoberta de mDNS local



if err := setupDiscovery(host); err != nil {



panic(err)



}

// junta ao tópico pubsub chamado librum

room := "librum"



topic, err := gossipSub.Join(room)



if err != nil {



panic(err)



}



// Cria o publicador(editor)



publish(ctx, topic)



}



// start publisher to topic



// inicia o editor no tópico



func publish(ctx context.Context, topic *pubsub.Topic) {



for {



scanner := bufio.NewScanner(os.Stdin)



for scanner.Scan() {



fmt.Printf("enter message to publish: \n")



msg := scanner.Text()



if len(msg) != 0 {




// Publica a mensagem no tópico



bytes := []byte(msg)



topic.Publish(ctx, bytes)



}



}



}



}





//  O discoveryNotifee é notificado quando encontrado um novo par via descoberta de mDNS




type discoveryNotifee struct {



h host.Host



}



// HandlePeerFound se conecta a pares descobertos via mDNS. Assim que estiverem conectados,



// o sistema PubSub começará a interagir automaticamente com eles se eles também



 // suportam PubSub.



func (n *discoveryNotifee) HandlePeerFound(pi peer.AddrInfo) {



fmt.Printf("discovered new peer %s\n", pi.ID.Pretty())



err := n.h.Connect(context.Background(), pi)



if err != nil {



fmt.Printf("error connecting to peer %s: %s\n", pi.ID.Pretty(), err)



}



}



// setupDiscovery cria um serviço de descoberta mDNS e o anexa ao Host libp2p.



// Isso nos permite descobrir automaticamente pares na mesma LAN e nos conectar a eles.



func setupDiscovery(h host.Host) error {



// Configura a descoberta de mDNS para encontrar pares locais



s := mdns.NewMdnsService(h, DiscoveryServiceTag, &discoveryNotifee{h: h})



return s.Start()



}








Enter fullscreen mode Exit fullscreen mode

Subiscritor gossipsub

Semelhante aos publicadores, criei dois tipos de pares de assinante para manter as coisas simples, pares de inicialização (pares públicos) e pares normais (pares por trás do NAT). Um assinante criou uma lista de inicialização vazia, então ele atua como um par de inicialização. Outro criado com o endereço IPFS do par de inicialização. A seguir está a implementação golang de assinantes. Eu adicionei comentários para descrever a função de cada linha no código.

  


package main



import (



"context"



"fmt"



"time"



"github.com/libp2p/go-libp2p"



"github.com/libp2p/go-libp2p-core/host"



"github.com/libp2p/go-libp2p-core/peer"



pubsub "github.com/libp2p/go-libp2p-pubsub"



"github.com/libp2p/go-libp2p/p2p/discovery/mdns"



"github.com/multiformats/go-multiaddr"



)



 // O DiscoveryInterval é a frequência com que re-publicamos nossos registros mDNS.



const DiscoveryInterval = time.Hour



// O DiscoveryServiceTag é usado em nossos anúncios mDNS para descobrir outros pares.



const DiscoveryServiceTag = "librum-pubsub"



func main() {



ctx := context.Background()



// cria um novo Host libp2p que escuta em uma porta TCP aleatória



host, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/7654"))



if err != nil {



panic(err)



}



 // ver detalhes e endereços do host



fmt.Printf("host ID %s\n", host.ID().Pretty())



fmt.Printf("following are the assigned addresses\n")



for _, addr := range host.Addrs() {



fmt.Printf("%s\n", addr.String())



}



fmt.Printf("\n")



// Cria um novo serviço PubSub usando o roteador GossipSub



gossipSub, err := pubsub.NewGossipSub(ctx, host)



if err != nil {



panic(err)



}



// Configura o DHT com pares de descoberta vazios



// Então este será um ponto  de descoberta para outros



// Este peer deve ser executado na nuvem (com endereço ip público)



discoveryPeers := []multiaddr.Multiaddr{}



dht, err := NewDHT(ctx, host, discoveryPeers)



if err != nil {



panic(err)



}



// Configura a descoberta de pares



go Discover(ctx, host, dht, "librum")



// Junta-se ao tópico pubsub chamado librum



room := "librum"



topic, err := gossipSub.Join(room)



if err != nil {



panic(err)



}





// subscrever-se no topico



subscriber, err := topic.Subscribe()



if err != nil {



panic(err)



}



subscribe(subscriber, ctx, host.ID())



}



 // inicia o assinante do tópico



func subscribe(subscriber *pubsub.Subscription, ctx context.Context, hostID peer.ID) {



for {



msg, err := subscriber.Next(ctx)



if err != nil {



panic(err)



}



// considera apenas as mensagens entregues por outros pares  



if msg.ReceivedFrom == hostID {



continue



}



fmt.Printf("got message: %s, from: %s\n", string(msg.Data), msg.ReceivedFrom.Pretty())



}



}



// discoveryNotifee é notificado quando encontramos um novo ponto  via descoberta de mDNS



type discoveryNotifee struct {



h host.Host



}



// HandlePeerFound se conecta os pares  descobertos via mDNS. Assim que estiverem conectados,



// O sistema PubSub começará a interagir automaticamente com eles se eles também



// suportem  PubSub.



func (n *discoveryNotifee) HandlePeerFound(pi peer.AddrInfo) {



fmt.Printf("discovered new peer %s\n", pi.ID.Pretty())



err := n.h.Connect(context.Background(), pi)



if err != nil {



fmt.Printf("error connecting to peer %s: %s\n", pi.ID.Pretty(), err)



}



}



// setupDiscovery cria um serviço de descoberta mDNS e o anexa ao Host libp2p.



// Isso nos permite descobrir automaticamente pares  na mesma LAN e nos conectar a eles.

func setupDiscovery(h host.Host) error {



// configura a descoberta de mDNS para encontrar pontos  locais



s := mdns.NewMdnsService(h, DiscoveryServiceTag, &discoveryNotifee{h: h})



return s.Start()



}





Enter fullscreen mode Exit fullscreen mode




package main



import (



"context"



"fmt"



"time"



"github.com/libp2p/go-libp2p"



"github.com/libp2p/go-libp2p-core/host"



"github.com/libp2p/go-libp2p-core/peer"



pubsub "github.com/libp2p/go-libp2p-pubsub"



"github.com/libp2p/go-libp2p/p2p/discovery/mdns"



"github.com/multiformats/go-multiaddr"



)



// O DiscoveryInterval é a frequência com que re-publicamos nossos registros mDNS.




const DiscoveryInterval = time.Hour



// O DiscoveryServiceTag é usado em nossos anúncios mDNS para descobrir outros pares.




const DiscoveryServiceTag = "librum-pubsub"



func main() {



ctx := context.Background()



// cria um novo Host libp2p que escuta em uma porta TCP aleatória



host, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/7654"))



if err != nil {



panic(err)



}



// ver detalhes e endereços do host



fmt.Printf("host ID %s\n", host.ID().Pretty())



fmt.Printf("following are the assigned addresses\n")



for _, addr := range host.Addrs() {



fmt.Printf("%s\n", addr.String())



}



fmt.Printf("\n")

// cria um novo serviço PubSub usando o roteador GossipSub



gossipSub, err := pubsub.NewGossipSub(ctx, host)



if err != nil {



panic(err)



}



// endereço ipfs dos pares de descoberta



// eu adicionei um par aqui, você pode adicionar vários pares de disovery



multiAddr, err := multiaddr.NewMultiaddr("/ip4/20.228.145.221/tcp/7654/p2p/QmPMFJUzfB1LrxksmpS75QNwtmN8TCEcMvSezL3V9hp8a4")



if err != nil {



panic(err)



}



println(multiAddr)



// configura DHT com servidor de descoberta



// este peer pode rodar atrás do nat(com endereço ip privado)



discoveryPeers := []multiaddr.Multiaddr{multiAddr}



dht, err := NewDHT(ctx, host, discoveryPeers)



if err != nil {



panic(err)



}



// configura a descoberta de pares



go Discover(ctx, host, dht, "librum")



// junta-se ao tópico pubsub chamado librum



room := "librum"



topic, err := gossipSub.Join(room)



if err != nil {



panic(err)



}



//subscrever-se no tópico



subscriber, err := topic.Subscribe()



if err != nil {



panic(err)



}



subscribe(subscriber, ctx, host.ID())



}



// inicia o assinante do tópico



func subscribe(subscriber *pubsub.Subscription, ctx context.Context, hostID peer.ID) {



for {



msg, err := subscriber.Next(ctx)



if err != nil {



panic(err)



}



// considera apenas mensagens entregues por outros pares



if msg.ReceivedFrom == hostID {



continue



}



fmt.Printf("got message: %s, from: %s\n", string(msg.Data), msg.ReceivedFrom.Pretty())



}



}



// O discoveryNotifee é notificado quando encontramos um novo peer via descoberta de mDNS

type discoveryNotifee struct {



h host.Host



}



// HandlePeerFound se conecta a pares descobertos via mDNS. Assim que estiverem conectados,



// o sistema PubSub começará a interagir automaticamente com eles se eles também



// suparterem  para o  PubSub.



func (n *discoveryNotifee) HandlePeerFound(pi peer.AddrInfo) {



fmt.Printf("discovered new peer %s\n", pi.ID.Pretty())



err := n.h.Connect(context.Background(), pi)



if err != nil {



fmt.Printf("error connecting to peer %s: %s\n", pi.ID.Pretty(), err)



}



}



// setupDiscovery cria um serviço de descoberta mDNS e o anexa ao Host libp2p.



// Isso nos permite descobrir automaticamente pares  na mesma LAN e nos conectar a eles.



func setupDiscovery(h host.Host) error {



// configura a descoberta de mDNS para encontrar pares  locais



s := mdns.NewMdnsService(h, DiscoveryServiceTag, &discoveryNotifee{h: h})



return s.Start()



}







Enter fullscreen mode Exit fullscreen mode


  

Executar aplicativo

A seguir está a maneira de construir e executar a aplicação. Eu já executei a inicialização do publicador e do assinante na nuvem AWS com IP público.. Publicador normal e assinante funcionam em máquina local. Os dados de publicação estarão disponíveis para os assinantes em tempo real. A comunicação de gossipsub acontece com sucesso através da Internet, utilizando o método de descoberta por pares DHT.

instalar dependências golang


go mod init



go mod tidy



---



#  construir editores e assinantes locais no diretório ./build



# executar na maquina local



go build -o build/subscriber src/subsciber.go src/dht.go src/discover.go



go build -o build/publisher src/publisher.go src/dht.go src/discover.go



---



# construir editor e assinante de bootstrap ./diretório build



# rodar na maquina local  



go build -o build/subscriberd src/bootstrap-subsciber.go src/dht.go src/discover.go



go build -o build/publisherd src/bootstrap-publisher.go src/dht.go src/discover.go



---



# rodar o iniciador de subscrição ( no terminal 1)



# rodar  na maquina aws



# coloca o endereço ipfs do  par como o endereço do peer de descoberta no local dos editores e assinantes



./build/subscriberd



# executa o assinante local (no terminal 2)



# executa no local na maquina  



./build/sbscriber



# executa o assinante local (no terminal 3)



# executa no local na maquina



./build/publisher  





Enter fullscreen mode Exit fullscreen mode

 

Segue a saída. A primeira guia do terminal é o par de assinante de inicialização que é executado na máquina AWS. A segunda guia do terminal executa o par de assinante local. A terceira guia do terminal executa o par do publicador local. Ao publicar mensagens do publicador local, elas estarão disponíveis no assinante local e nos assinantes da AWS.   

AWS

Referências

1.  https://ldej.nl/post/building-an-echo-application-with-libp2p/

2.  https://gist.github.com/upperwal/38cd0c98e4a6b34c061db0ff26def9b9#file-libp2p_chat_bootstrapping-md

3.  https://github.com/libp2p/go-libp2p/blob/master/examples/chat-with-rendezvous/chat.go

4.  https://codethechange.stanford.edu/guides/guide_kademlia.html

5.  https://github.com/libp2p/js-libp2p-kad-dht

Este artigo foi escrito por λ.eranga, e traduzido por AIengineer13. 
Encontre o artigo original aqui.


Abrace a oportunidade de elevar sua jornada de desenvolvimento para um nível superior. Pares libp2p é apenas o começo; os builds incríveis da WEB3DEV representam a chave de entrada para o emocionante cenário web3. 🚀🧑‍💻

Não perca tempo, 👉inscreva-se👈 agora mesmo e comece a desbravar o universo Blockchain!
 
Seja também WEB3DEV!

Top comments (0)