You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Jorropo ae1645d24e
examples/chat-with-mdns: default to a random port (#2896)
3 months ago
..
.gitignore Add .gitignore for each example 4 years ago
README.md chore: update chat-with-mdns example readme (#2678) 10 months ago
flags.go examples/chat-with-mdns: default to a random port (#2896) 3 months ago
main.go examples: call NewStream from only one side (#2677) 10 months ago
mdns.go examples: update go-libp2p to v0.30.0 (#2507) 1 year ago

README.md

p2p chat app with libp2p [support peer discovery using mdns]

This program demonstrates a simple p2p chat application. You will learn how to discover a peer in the network (using mdns), connect to it and open a chat stream. This example is heavily influenced by (and shamelessly copied from) chat-with-rendezvous example

How to build this example?

go get -v -d ./...

go build

Usage

Use two different terminal windows to run

./chat-with-mdns -port 6666
./chat-with-mdns -port 6668

So how does it work?

  1. Configure a p2p host
ctx := context.Background()

// libp2p.New constructs a new libp2p Host.
// Other options can be added here.
host, err := libp2p.New()

libp2p.New is the constructor for libp2p node. It creates a host with given configuration.

  1. Set a default handler function for incoming connections.

This function is called on the local peer when a remote peer initiate a connection and starts a stream with the local peer.

// Set a function as stream handler.
host.SetStreamHandler("/chat/1.1.0", handleStream)

handleStream is executed for each new stream incoming to the local peer. stream is used to exchange data between local and remote peer. This example uses non blocking functions for reading and writing from this stream.

func handleStream(stream net.Stream) {

    // Create a buffer stream for non blocking read and write.
    rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

    go readData(rw)
    go writeData(rw)

    // 'stream' will stay open until you close it (or the other side closes it).
}
  1. Find peers nearby using mdns

New mdns discovery service in host.

notifee := &discoveryNotifee{PeerChan: make(chan peer.AddrInfo)}
ser, err := discovery.NewMdnsService(peerhost, rendezvous, notifee)

register Notifee interface with service so that we get notified about peer discovery

	ser.Start()
  1. Open streams to peers found.

Finally we open stream to the peers we found, as we find them

	peer := <-peerChan // will block until we discover a peer
	// this is used to avoid call `NewStream` from both side
	if peer.ID > host.ID() {
		// if other end peer id greater than us, don't connect to it, just wait for it to connect us
		fmt.Println("Found peer:", peer, " id is greater than us, wait for it to connect to us")
		continue
	}
	fmt.Println("Found peer:", peer, ", connecting")

	if err := host.Connect(ctx, peer); err != nil {
		fmt.Println("Connection failed:", err)
		continue
	}

	// open a stream, this stream will be handled by handleStream other end
	stream, err := host.NewStream(ctx, peer.ID, protocol.ID(cfg.ProtocolID))

	if err != nil {
		fmt.Println("Stream open failed", err)
	} else {
		rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))

		go writeData(rw)
		go readData(rw)
		fmt.Println("Connected to:", peer)
	}

Authors

  1. Bineesh Lazar