81 lines
1.9 KiB
Go
81 lines
1.9 KiB
Go
package p2p
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"fmt"
|
|
|
|
host "github.com/libp2p/go-libp2p/core/host"
|
|
libp2p "github.com/libp2p/go-libp2p"
|
|
"github.com/libp2p/go-libp2p/core/crypto"
|
|
"github.com/libp2p/go-libp2p/core/network"
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
)
|
|
|
|
const ProtocolID = "/dejo/1.0.0"
|
|
|
|
// P2PNode representa um nó da rede P2P da DEJO.
|
|
type P2PNode struct {
|
|
Host host.Host
|
|
PeerChan chan peer.AddrInfo
|
|
}
|
|
|
|
// NewP2PNode cria um novo nó libp2p.
|
|
func NewP2PNode(ctx context.Context) (*P2PNode, error) {
|
|
priv, _, _ := crypto.GenerateKeyPairWithReader(crypto.Ed25519, -1, rand.Reader)
|
|
|
|
h, err := libp2p.New(
|
|
libp2p.Identity(priv),
|
|
libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0"),
|
|
)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
node := &P2PNode{
|
|
Host: h,
|
|
PeerChan: make(chan peer.AddrInfo),
|
|
}
|
|
|
|
// Handler para conexões recebidas
|
|
h.SetStreamHandler(ProtocolID, func(s network.Stream) {
|
|
buf := make([]byte, 1024)
|
|
s.Read(buf)
|
|
fmt.Printf("📡 Recebido: %s\n", string(buf))
|
|
s.Close()
|
|
})
|
|
|
|
return node, nil
|
|
}
|
|
|
|
// HandlePeerFound é chamado quando um novo peer é descoberto.
|
|
func (p *P2PNode) HandlePeerFound(pi peer.AddrInfo) {
|
|
fmt.Println("👋 Novo peer descoberto:", pi.ID)
|
|
p.PeerChan <- pi
|
|
}
|
|
|
|
// ConnectToPeers tenta se conectar aos peers encontrados.
|
|
func (p *P2PNode) ConnectToPeers(ctx context.Context) {
|
|
go func() {
|
|
for pi := range p.PeerChan {
|
|
if err := p.Host.Connect(ctx, pi); err != nil {
|
|
fmt.Println("Erro ao conectar ao peer:", err)
|
|
} else {
|
|
fmt.Println("🔗 Conectado ao peer:", pi.ID)
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
// Broadcast envia uma mensagem para todos os peers conectados.
|
|
func (p *P2PNode) Broadcast(msg string) {
|
|
for _, c := range p.Host.Network().Peers() {
|
|
stream, err := p.Host.NewStream(context.Background(), c, ProtocolID)
|
|
if err != nil {
|
|
fmt.Println("Erro ao abrir stream:", err)
|
|
continue
|
|
}
|
|
stream.Write([]byte(msg))
|
|
stream.Close()
|
|
}
|
|
} |