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

chore: bring examples back into repository and add tests #1092

Merged
merged 10 commits into from
May 12, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
13 changes: 11 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
*.swp
examples/chat/chat
examples/chat-with-mdns/chat-with-mdns
examples/chat-with-rendezvous/chat-with-rendezvous
examples/chat-with-rendezvous/chat
examples/echo/echo
examples/multicodecs/multicodecs
.idea
examples/http-proxy/http-proxy
examples/libp2p-host/libp2p-host
examples/multipro/multipro
examples/pubsub/chat
examples/relay/relay
examples/routed-echo/routed-echo
.idea
Stebalien marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ As new releases of go-libp2p are made available, you can upgrade your applicatio

### Examples

Examples can be found in the [examples repo](https://github.com/libp2p/go-libp2p-examples).
Examples can be found on the [examples folder](examples).
iand marked this conversation as resolved.
Show resolved Hide resolved

## Development

Expand Down Expand Up @@ -180,7 +180,6 @@ List of packages currently in existence for libp2p:
| [`go-libp2p-http`](//github.com/libp2p/go-libp2p-http) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-http.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-http) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-http/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-http) | HTTP on top of libp2p streams |
| **Testing and examples** |
| [`go-libp2p-testing`](//github.com/libp2p/go-libp2p-testing) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-testing.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-testing) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-testing/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-testing) | a collection of testing utilities for libp2p |
| [`go-libp2p-examples`](//github.com/libp2p/go-libp2p-examples) | [![Travis CI](https://travis-ci.com/libp2p/go-libp2p-examples.svg?branch=master)](https://travis-ci.com/libp2p/go-libp2p-examples) | [![codecov](https://codecov.io/gh/libp2p/go-libp2p-examples/branch/master/graph/badge.svg)](https://codecov.io/gh/libp2p/go-libp2p-examples) | go-libp2p examples and tutorials |
iand marked this conversation as resolved.
Show resolved Hide resolved

# Contribute

Expand Down
11 changes: 11 additions & 0 deletions examples/.circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
iand marked this conversation as resolved.
Show resolved Hide resolved
jobs:
build:
docker:
- image: circleci/golang:1.13
environment:
GO111MODULE: "on"
steps:
- checkout
- run: go test -v -race -bench . ./...
- run: GOARCH=386 go test github.com/libp2p/... || true
30 changes: 30 additions & 0 deletions examples/.travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
os:
iand marked this conversation as resolved.
Show resolved Hide resolved
- linux

language: go

go:
- 1.13.x

env:
global:
- GOTFLAGS="-race"
matrix:
- BUILD_DEPTYPE=gomod


# disable travis install
install:
- true

script:
- bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh)


cache:
directories:
- $GOPATH/pkg/mod
- $HOME/.cache/go-build

notifications:
email: false
21 changes: 21 additions & 0 deletions examples/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)
iand marked this conversation as resolved.
Show resolved Hide resolved

Copyright (c) 2018 Protocol Labs

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
42 changes: 40 additions & 2 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
# go-libp2p Examples
# `go-libp2p` examples and tutorials
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any real reason to quote this?


The go-libp2p examples have moved to [go-libp2p-examples](https://github.com/libp2p/go-libp2p-examples).
[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai)
[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/)
[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p)
[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io)
Comment on lines +3 to +6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably don't need these, given the root README.


In this folder, you can find a variety of examples to help you get started in using go-libp2p. Every example as a specific purpose and some of each incorporate a full tutorial that you can follow through, helping you expand your knowledge about libp2p and p2p networks in general.

Let us know if you find any issue or if you want to contribute and add a new tutorial, feel welcome to submit a pr, thank you!

## Examples and Tutorials

- [The libp2p 'host'](./libp2p-host)
- [Building an http proxy with libp2p](./http-proxy)
- [An echo host](./echo)
- [Multicodecs with protobufs](./multipro)
- [P2P chat application](./chat)
- [P2P chat application w/ rendezvous peer discovery](./chat-with-rendezvous)
- [P2P chat application with peer discovery using mdns](./chat-with-mdns)
- [A chapter based approach to building a libp2p application](./ipfs-camp-2019/) _Created for [IPFS Camp 2019](https://github.com/ipfs/camp/tree/master/CORE_AND_ELECTIVE_COURSES/CORE_COURSE_B)_

For js-libp2p examples, check https://github.com/libp2p/js-libp2p/tree/master/examples

## Troubleshooting

When building the examples ensure you have a clean `$GOPATH`. If you have checked out and built other `libp2p` repos then you may get errors similar to the one below when building the examples. Note that the use of the `gx` package manager **is not required** to run the examples or to use `libp2p`.
```
$:~/go/src/github.com/libp2p/go-libp2p-examples/libp2p-host$ go build host.go
# command-line-arguments
./host.go:36:18: cannot use priv (type "github.com/libp2p/go-libp2p-crypto".PrivKey) as type "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto".PrivKey in argument to libp2p.Identity:
"github.com/libp2p/go-libp2p-crypto".PrivKey does not implement "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto".PrivKey (wrong type for Equals method)
have Equals("github.com/libp2p/go-libp2p-crypto".Key) bool
want Equals("gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto".Key) bool
```

To obtain a clean `$GOPATH` execute the following:
```
> mkdir /tmp/libp2p-examples
> export GOPATH=/tmp/libp2p/examples
```
100 changes: 100 additions & 0 deletions examples/chat-with-mdns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# 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**
```go
ctx := context.Background()

// libp2p.New constructs a new libp2p Host.
// Other options can be added here.
host, err := libp2p.New(ctx)
```
[libp2p.New](https://godoc.org/github.com/libp2p/go-libp2p#New) is the constructor for libp2p node. It creates a host with given configuration.

2. **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.
```go
// 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.

```go
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).
}
```

3. **Find peers nearby using mdns**

Start [mdns discovery](https://godoc.org/github.com/libp2p/go-libp2p/p2p/discovery#NewMdnsService) service in host.

```go
ser, err := discovery.NewMdnsService(ctx, peerhost, time.Hour, rendezvous)
```
register [Notifee interface](https://godoc.org/github.com/libp2p/go-libp2p/p2p/discovery#Notifee) with service so that we get notified about peer discovery

```go
n := &discoveryNotifee{}
ser.RegisterNotifee(n)
```


4. **Open streams to peers found.**

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

```go
peer := <-peerChan // will block untill we discover a peer
fmt.Println("Found peer:", peer, ", connecting")

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

// 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
24 changes: 24 additions & 0 deletions examples/chat-with-mdns/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package main

import (
"flag"
)

type config struct {
RendezvousString string
ProtocolID string
listenHost string
listenPort int
}

func parseFlags() *config {
c := &config{}

flag.StringVar(&c.RendezvousString, "rendezvous", "meetme", "Unique string to identify group of nodes. Share this with your friends to let them connect with you")
flag.StringVar(&c.listenHost, "host", "0.0.0.0", "The bootstrap node host listen address\n")
flag.StringVar(&c.ProtocolID, "pid", "/chat/1.1.0", "Sets a protocol id for stream headers")
flag.IntVar(&c.listenPort, "port", 4001, "node listen port")

flag.Parse()
return c
}
Loading