Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update and fix examples #2760

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Let us know if you find any issue or if you want to contribute and add a new tut
- [The libp2p 'host'](./libp2p-host)
- [Building an http proxy with libp2p](./http-proxy)
- [An echo host](./echo)
- [Routed echo host](./routed-echo/)
- [Multicodecs with protobufs](./multipro)
- [P2P chat application](./chat)
- [P2P chat application w/ rendezvous peer discovery](./chat-with-rendezvous)
Expand Down
108 changes: 51 additions & 57 deletions examples/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,50 +48,6 @@ import (
"github.com/multiformats/go-multiaddr"
)

func handleStream(s network.Stream) {
log.Println("Got a new stream!")

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

go readData(rw)
go writeData(rw)

// stream 's' will stay open until you close it (or the other side closes it).
}

func readData(rw *bufio.ReadWriter) {
for {
str, _ := rw.ReadString('\n')

if str == "" {
return
}
if str != "\n" {
// Green console colour: \x1b[32m
// Reset console colour: \x1b[0m
fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
}

}
}

func writeData(rw *bufio.ReadWriter) {
stdReader := bufio.NewReader(os.Stdin)

for {
fmt.Print("> ")
sendData, err := stdReader.ReadString('\n')
if err != nil {
log.Println(err)
return
}

rw.WriteString(fmt.Sprintf("%s\n", sendData))
rw.Flush()
}
}

func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down Expand Up @@ -132,22 +88,61 @@ func main() {
if *dest == "" {
startPeer(ctx, h, handleStream)
} else {
rw, err := startPeerAndConnect(ctx, h, *dest)
err := startPeerAndConnect(ctx, h, *dest)
if err != nil {
log.Println(err)
return
}

// Create a thread to read and write data.
go writeData(rw)
go readData(rw)

}

// Wait forever
select {}
}

func handleStream(s network.Stream) {
log.Println("Got a new stream!")

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

go readData(rw)
go writeData(rw)

// stream 's' will stay open until you close it (or the other side closes it).
}

func readData(rw *bufio.ReadWriter) {
for {
str, _ := rw.ReadString('\n')

if str == "" {
return
}
if str != "\n" {
// Green console colour: \x1b[32m
// Reset console colour: \x1b[0m
fmt.Printf("\x1b[32m%s\x1b[0m> ", str)
}

}
}

func writeData(rw *bufio.ReadWriter) {
stdReader := bufio.NewReader(os.Stdin)

for {
fmt.Print("> ")
sendData, err := stdReader.ReadString('\n')
if err != nil {
log.Println(err)
return
}

rw.WriteString(fmt.Sprintf("%s\n", sendData))
rw.Flush()
}
}

func makeHost(port int, randomness io.Reader) (host.Host, error) {
// Creates a new RSA key pair for this host.
prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, randomness)
Expand Down Expand Up @@ -193,7 +188,7 @@ func startPeer(ctx context.Context, h host.Host, streamHandler network.StreamHan
log.Println()
}

func startPeerAndConnect(ctx context.Context, h host.Host, destination string) (*bufio.ReadWriter, error) {
func startPeerAndConnect(ctx context.Context, h host.Host, destination string) error {
log.Println("This node's multiaddresses:")
for _, la := range h.Addrs() {
log.Printf(" - %v\n", la)
Expand All @@ -204,14 +199,14 @@ func startPeerAndConnect(ctx context.Context, h host.Host, destination string) (
maddr, err := multiaddr.NewMultiaddr(destination)
if err != nil {
log.Println(err)
return nil, err
return err
}

// Extract the peer ID from the multiaddr.
info, err := peer.AddrInfoFromP2pAddr(maddr)
if err != nil {
log.Println(err)
return nil, err
return err
}

// Add the destination's peer multiaddress in the peerstore.
Expand All @@ -223,12 +218,11 @@ func startPeerAndConnect(ctx context.Context, h host.Host, destination string) (
s, err := h.NewStream(context.Background(), info.ID, "/chat/1.0.0")
if err != nil {
log.Println(err)
return nil, err
return err
}
log.Println("Established connection to destination")

// Create a buffered stream so that read and writes are non-blocking.
rw := bufio.NewReadWriter(bufio.NewReader(s), bufio.NewWriter(s))
handleStream(s)

return rw, nil
return nil
}
99 changes: 49 additions & 50 deletions examples/http-proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,55 @@ import (
// libp2p handle them to the right handler functions.
const Protocol = "/proxy-example/0.0.1"

const help = `
This example creates a simple HTTP Proxy using two libp2p peers. The first peer
provides an HTTP server locally which tunnels the HTTP requests with libp2p
to a remote peer. The remote peer performs the requests and
send the sends the response back.

Usage: Start remote peer first with: ./proxy
Then start the local peer with: ./proxy -d <remote-peer-multiaddress>

Then you can do something like: curl -x "localhost:9900" "http://ipfs.io".
This proxies sends the request through the local peer, which proxies it to
the remote peer, which makes it and sends the response back.`

func main() {
flag.Usage = func() {
fmt.Println(help)
flag.PrintDefaults()
}

// Parse some flags
destPeer := flag.String("d", "", "destination peer address")
port := flag.Int("p", 9900, "proxy port")
p2pport := flag.Int("l", 12000, "libp2p listen port")
flag.Parse()

// If we have a destination peer we will start a local server
if *destPeer != "" {
// We use p2pport+1 in order to not collide if the user
// is running the remote peer locally on that port
host := makeRandomHost(*p2pport + 1)
// Make sure our host knows how to reach destPeer
destPeerID := addAddrToPeerstore(host, *destPeer)
proxyAddr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", *port))
if err != nil {
log.Fatalln(err)
}
// Create the proxy service and start the http server
proxy := NewProxyService(host, proxyAddr, destPeerID)
proxy.Serve() // serve hangs forever
} else {
host := makeRandomHost(*p2pport)
// In this case we only need to make sure our host
// knows how to handle incoming proxied requests from
// another peer.
_ = NewProxyService(host, nil, "")
<-make(chan struct{}) // hang forever
}
}

// makeRandomHost creates a libp2p host with a randomly generated identity.
// This step is described in depth in other tutorials.
func makeRandomHost(port int) host.Host {
Expand Down Expand Up @@ -221,53 +270,3 @@ func addAddrToPeerstore(h host.Host, addr string) peer.ID {
h.Peerstore().AddAddr(peerid, targetAddr, peerstore.PermanentAddrTTL)
return peerid
}

const help = `
This example creates a simple HTTP Proxy using two libp2p peers. The first peer
provides an HTTP server locally which tunnels the HTTP requests with libp2p
to a remote peer. The remote peer performs the requests and
send the sends the response back.

Usage: Start remote peer first with: ./proxy
Then start the local peer with: ./proxy -d <remote-peer-multiaddress>

Then you can do something like: curl -x "localhost:9900" "http://ipfs.io".
This proxies sends the request through the local peer, which proxies it to
the remote peer, which makes it and sends the response back.`

func main() {
flag.Usage = func() {
fmt.Println(help)
flag.PrintDefaults()
}

// Parse some flags
destPeer := flag.String("d", "", "destination peer address")
port := flag.Int("p", 9900, "proxy port")
p2pport := flag.Int("l", 12000, "libp2p listen port")
flag.Parse()

// If we have a destination peer we will start a local server
if *destPeer != "" {
// We use p2pport+1 in order to not collide if the user
// is running the remote peer locally on that port
host := makeRandomHost(*p2pport + 1)
// Make sure our host knows how to reach destPeer
destPeerID := addAddrToPeerstore(host, *destPeer)
proxyAddr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", *port))
if err != nil {
log.Fatalln(err)
}
// Create the proxy service and start the http server
proxy := NewProxyService(host, proxyAddr, destPeerID)
proxy.Serve() // serve hangs forever
} else {
host := makeRandomHost(*p2pport)
// In this case we only need to make sure our host
// knows how to handle incoming proxied requests from
// another peer.
_ = NewProxyService(host, nil, "")
<-make(chan struct{}) // hang forever
}

}
39 changes: 29 additions & 10 deletions examples/libp2p-host/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ If you want more control over the configuration, you can specify some options to
In this snippet we set a number of useful options like a custom ID and enable routing. This will improve discoverability and reachability of the peer on NAT'ed environments:

```go
import (
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/routing"

libp2ptls "github.com/libp2p/go-libp2p/p2p/security/tls"
libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
)

// The context governs the lifetime of the libp2p node.
// Cancelling it will stop the host.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// Set your own keypair
priv, _, err := crypto.GenerateKeyPair(
crypto.Ed25519, // Select your key type. Ed25519 are nice short
Expand All @@ -41,6 +55,12 @@ if err != nil {

var idht *dht.IpfsDHT

connmgr, err := connmgr.NewConnManager(
100, // Lowwater
400, // HighWater,
connmgr.WithGracePeriod(time.Minute),
)

h2, err := libp2p.New(
// Use the keypair we generated
libp2p.Identity(priv),
Expand All @@ -59,23 +79,22 @@ h2, err := libp2p.New(
libp2p.DefaultTransports,
// Let's prevent our peer from having too many
// connections by attaching a connection manager.
libp2p.ConnectionManager(connmgr.NewConnManager(
100, // Lowwater
400, // HighWater,
time.Minute, // GracePeriod
)),
libp2p.ConnectionManager(connmgr),
// Attempt to open ports using uPNP for NATed hosts.
libp2p.NATPortMap(),
// Let this host use the DHT to find other hosts
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
idht, err = dht.New(ctx, h)
return idht, err
}),
// Let this host use relays and advertise itself on relays if
// it finds it is behind NAT. Use libp2p.Relay(options...) to
// enable active relays and more.
libp2p.EnableAutoRelay(),
)
// If you want to help other peers to figure out if they are behind
// NATs, you can launch the server-side of AutoNAT too (AutoRelay
// already runs the client)
//
// This service is highly rate-limited and should not cause any
// performance issues.
libp2p.EnableNATService(),
)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion examples/routed-echo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ From `go-libp2p/examples` base folder:
2018/02/19 12:22:32 listening for connections
```

The listener libp2p host will print its randomly generated Base58 encoded ID string, which combined with the ipfs DHT, can be used to reach the host, despite lacking other connection details. By default, this example will bootstrap off your local IPFS peer (assuming one is running). If you'd rather bootstrap off the same peers go-ipfs uses, pass the `-global` flag in both terminals.
The listener libp2p host will print its randomly generated Base58 encoded ID string, which combined with the ipfs DHT, can be used to reach the host, despite lacking other connection details. By **default**, this example will bootstrap off your **local IPFS peer** (assuming one is running). If you'd rather bootstrap off the same peers go-ipfs uses, pass the `-global` flag in both terminals.

Now, launch another node that talks to the listener:

Expand Down