Skip to content

Instantly share code, notes, and snippets.

@bigs
Created May 18, 2018 00:20
Show Gist options
  • Select an option

  • Save bigs/d9eaa34b2e00fca31c70121c8fda84b1 to your computer and use it in GitHub Desktop.

Select an option

Save bigs/d9eaa34b2e00fca31c70121c8fda84b1 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"context"
"fmt"
"os"
"time"
cid "github.com/ipfs/go-cid"
datastore "github.com/ipfs/go-datastore"
ipfsaddr "github.com/ipfs/go-ipfs-addr"
"github.com/libp2p/go-floodsub"
"github.com/libp2p/go-libp2p"
libp2pdht "github.com/libp2p/go-libp2p-kad-dht"
peerstore "github.com/libp2p/go-libp2p-peerstore"
"github.com/multiformats/go-multihash"
//"github.com/libp2p/go-libp2p-host"
)
func main() {
TopicName := "libp2p-demo-chat"
ctx := context.Background()
// Set up a libp2p host.
host, err := libp2p.New(ctx, libp2p.Defaults)
if err != nil {
panic(err)
}
for _, addr := range host.Addrs() {
fmt.Printf("- go run main.go %s/ipfs/%s\n", addr.String(), host.ID().Pretty())
}
// Construct ourselves a pubsub instance using that libp2p host.
fsub, err := floodsub.NewFloodSub(ctx, host)
if err != nil {
panic(err)
}
// Using a DHT for discovery.
dht := libp2pdht.NewDHTClient(ctx, host, datastore.NewMapDatastore())
if err != nil {
panic(err)
}
bsConfig := libp2pdht.DefaultBootstrapConfig
bsConfig.Period = 5 * time.Second
bsConfig.Queries = 1000
if _, err := dht.BootstrapWithConfig(bsConfig); err != nil {
panic(err)
}
bootstrapPeers := os.Args[1:]
fmt.Println("bootstrapping...")
for _, addr := range bootstrapPeers {
iaddr, err := ipfsaddr.ParseString(addr)
if err != nil {
panic(err)
}
pinfo, err := peerstore.InfoFromP2pAddr(iaddr.Multiaddr())
if err != nil {
panic(err)
}
if err := host.Connect(ctx, *pinfo); err != nil {
fmt.Println("bootstrapping to peer failed: ", err)
}
}
// Using the sha256 of our "topic" as our rendezvous value
c, _ := cid.NewPrefixV1(cid.Raw, multihash.SHA2_256).Sum([]byte(TopicName))
// First, announce ourselves as participating in this topic
fmt.Println("announcing ourselves...")
tctx, _ := context.WithTimeout(ctx, time.Second*10)
if err := dht.Provide(tctx, c, true); err != nil {
panic(err)
}
// Now, look for others who have announced
fmt.Println("searching for other peers...")
tctx, _ = context.WithTimeout(ctx, time.Second*10)
peers, err := dht.FindProviders(tctx, c)
if err != nil {
panic(err)
}
fmt.Printf("Found %d peers!\n", len(peers))
// Now connect to them!
for _, p := range peers {
if p.ID == host.ID() {
// No sense connecting to ourselves
continue
}
tctx, _ := context.WithTimeout(ctx, time.Second*5)
if err := host.Connect(tctx, p); err != nil {
fmt.Println("failed to connect to peer: ", err)
}
}
fmt.Println("bootstrapping and discovery complete!")
sub, err := fsub.Subscribe(TopicName)
if err != nil {
panic(err)
}
// Go and listen for messages from them, and print them to the screen
go func() {
for {
msg, err := sub.Next(ctx)
if err != nil {
panic(err)
}
fmt.Printf("%s: %s\n", msg.GetFrom(), string(msg.GetData()))
}
}()
// Now, wait for input from the user, and send that out!
fmt.Println("Type something and hit enter to send:")
scan := bufio.NewScanner(os.Stdin)
for scan.Scan() {
if err := fsub.Publish(TopicName, scan.Bytes()); err != nil {
panic(err)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment