README.md 3.71 KB
Newer Older
Lars Gierth's avatar
Lars Gierth committed
1
2
# Echo client/server with libp2p

Hector Sanjuan's avatar
Hector Sanjuan committed
3
4
5
This is an example that quickly shows how to use the `go-libp2p` stack,
including Host/Basichost, Network/Swarm, Streams, Peerstores and
Multiaddresses.
Lars Gierth's avatar
Lars Gierth committed
6

Hector Sanjuan's avatar
Hector Sanjuan committed
7
This example can be started in either listen mode, or dial mode.
Lars Gierth's avatar
Lars Gierth committed
8

Hector Sanjuan's avatar
Hector Sanjuan committed
9
10
In listen mode, it will sit and wait for incoming connections on the
`/echo/1.0.0` protocol. Whenever it receives a stream, it will write the
Justin's avatar
Justin committed
11
message `"Hello, world!"` over the stream and close it.
Hector Sanjuan's avatar
Hector Sanjuan committed
12
13
14

In dial mode, the node will start up, connect to the given address, open a
stream to the target peer, and read a message on the protocol `/echo/1.0.0`.
Lars Gierth's avatar
Lars Gierth committed
15
16
17

## Build

Hector Sanjuan's avatar
Hector Sanjuan committed
18
19
From `go-libp2p` base folder:

Jeromy's avatar
Jeromy committed
20
```
Lars Gierth's avatar
Lars Gierth committed
21
> make deps
Justin's avatar
Justin committed
22
> go build ./examples/echo
Jeromy's avatar
Jeromy committed
23
24
25
```

## Usage
Lars Gierth's avatar
Lars Gierth committed
26

Jeromy's avatar
Jeromy committed
27
```
Justin's avatar
Justin committed
28
> ./echo -l 1235
Justin's avatar
Justin committed
29
2016/11/10 10:45:37 I am /ip4/127.0.0.1/tcp/1235/ipfs/QmNtX1cvrm2K6mQmMEaMxAuB4rTexhd87vpYVot4sEZzxc
Hector Sanjuan's avatar
Hector Sanjuan committed
30
2016/11/10 10:45:37 listening for connections
Jeromy's avatar
Jeromy committed
31
32
```

Hector Sanjuan's avatar
Hector Sanjuan committed
33
34
35
36
The listener libp2p host will print its `Multiaddress`, which indicates how it
can be reached (ip4+tcp) and its randomly generated ID (`QmNtX1cv...`)

Now, launch another node that talks to the listener:
Jeromy's avatar
Jeromy committed
37
38

```
Justin's avatar
Justin committed
39
> ./echo -d /ip4/127.0.0.1/tcp/1235/ipfs/QmNtX1cvrm2K6mQmMEaMxAuB4rTexhd87vpYVot4sEZzxc -l 1236
Jeromy's avatar
Jeromy committed
40
```
Hector Sanjuan's avatar
Hector Sanjuan committed
41

Justin's avatar
Justin committed
42
The new node with send the message `"Hello, world!"` to the
Hector Sanjuan's avatar
Hector Sanjuan committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
listener, which will in turn echo it over the stream and close it. The
listener logs the message, and the sender logs the response.

## Details

The `makeBasicHost()` function creates a
[go-libp2p-basichost](https://godoc.org/github.com/libp2p/go-libp2p/p2p/host/basic)
object. `basichost` objects wrap
[go-libp2 swarms](https://godoc.org/github.com/libp2p/go-libp2p-swarm#Swarm)
and should be used preferentially. A
[go-libp2p-swarm Network](https://godoc.org/github.com/libp2p/go-libp2p-swarm#Network)
is a `swarm` which complies to the
[go-libp2p-net Network interface](https://godoc.org/github.com/libp2p/go-libp2p-net#Network)
and takes care of maintaining streams, connections, multiplexing different
protocols on them, handling incoming connections etc.

In order to create the swarm (and a `basichost`), the example needs:

  * An
    [ipfs-procotol ID](https://godoc.org/github.com/libp2p/go-libp2p-peer#ID)
    like `QmNtX1cvrm2K6mQmMEaMxAuB4rTexhd87vpYVot4sEZzxc`. The example
    autogenerates this on every run. An optional key-pair to secure
    communications can be added to it. The example autogenerates them when
    using `-secio`.
  * A [Multiaddress](https://godoc.org/github.com/multiformats/go-multiaddr),
    which indicates how to reach this peer. There can be several of them
    (using different protocols or locations for example). Example:
    `/ip4/127.0.0.1/tcp/1234`.
  * A
    [go-libp2p-peerstore](https://godoc.org/github.com/libp2p/go-libp2p-peerstore),
    which is used as a address book which matches node IDs to the
    multiaddresses through which they can be contacted. This peerstore gets
    autopopulated when manually opening a connection (with
    [`Connect()`](https://godoc.org/github.com/libp2p/go-libp2p/p2p/host/basic#BasicHost.Connect). Alternatively,
    we can manually
    [`AddAddr()`](https://godoc.org/github.com/libp2p/go-libp2p-peerstore#AddrManager.AddAddr)
    as in the example.

A `basichost` can now open streams (bi-directional channel between to peers)
using
[NewStream](https://godoc.org/github.com/libp2p/go-libp2p/p2p/host/basic#BasicHost.NewStream)
and use them to send and receive data tagged with a `Protocol.ID` (a
string). The host can also listen for incoming connections for a given
`Protocol` with
[`SetStreamHandle()`](https://godoc.org/github.com/libp2p/go-libp2p/p2p/host/basic#BasicHost.SetStreamHandler).

The example makes use of all of this to enable communication between a
listener and a sender using protocol `/echo/1.0.0` (which could be any other thing).