OSDN Git Service

Merge branch 'dev' into dev-verify
[bytom/bytom.git] / p2p / README.md
1 # `tendermint/tendermint/p2p`
2
3 [![CircleCI](https://circleci.com/gh/tendermint/tendermint/p2p.svg?style=svg)](https://circleci.com/gh/tendermint/tendermint/p2p)
4
5 `tendermint/tendermint/p2p` provides an abstraction around peer-to-peer communication.<br/>
6
7 ## Peer/MConnection/Channel
8
9 Each peer has one `MConnection` (multiplex connection) instance.
10
11 __multiplex__ *noun* a system or signal involving simultaneous transmission of
12 several messages along a single channel of communication.
13
14 Each `MConnection` handles message transmission on multiple abstract communication
15 `Channel`s.  Each channel has a globally unique byte id.
16 The byte id and the relative priorities of each `Channel` are configured upon
17 initialization of the connection.
18
19 There are two methods for sending messages:
20 ```go
21 func (m MConnection) Send(chID byte, msg interface{}) bool {}
22 func (m MConnection) TrySend(chID byte, msg interface{}) bool {}
23 ```
24
25 `Send(chID, msg)` is a blocking call that waits until `msg` is successfully queued
26 for the channel with the given id byte `chID`.  The message `msg` is serialized
27 using the `tendermint/wire` submodule's `WriteBinary()` reflection routine.
28
29 `TrySend(chID, msg)` is a nonblocking call that returns false if the channel's
30 queue is full.
31
32 `Send()` and `TrySend()` are also exposed for each `Peer`.
33
34 ## Switch/Reactor
35
36 The `Switch` handles peer connections and exposes an API to receive incoming messages
37 on `Reactors`.  Each `Reactor` is responsible for handling incoming messages of one
38 or more `Channels`.  So while sending outgoing messages is typically performed on the peer,
39 incoming messages are received on the reactor.
40
41 ```go
42 // Declare a MyReactor reactor that handles messages on MyChannelID.
43 type MyReactor struct{}
44
45 func (reactor MyReactor) GetChannels() []*ChannelDescriptor {
46     return []*ChannelDescriptor{ChannelDescriptor{ID:MyChannelID, Priority: 1}}
47 }
48
49 func (reactor MyReactor) Receive(chID byte, peer *Peer, msgBytes []byte) {
50     r, n, err := bytes.NewBuffer(msgBytes), new(int64), new(error)
51     msgString := ReadString(r, n, err)
52     fmt.Println(msgString)
53 }
54
55 // Other Reactor methods omitted for brevity
56 ...
57
58 switch := NewSwitch([]Reactor{MyReactor{}})
59
60 ...
61
62 // Send a random message to all outbound connections
63 for _, peer := range switch.Peers().List() {
64     if peer.IsOutbound() {
65         peer.Send(MyChannelID, "Here's a random message")
66     }
67 }
68 ```
69
70 ### PexReactor/AddrBook
71
72 A `PEXReactor` reactor implementation is provided to automate peer discovery.
73
74 ```go
75 book := p2p.NewAddrBook(addrBookFilePath)
76 pexReactor := p2p.NewPEXReactor(book)
77 ...
78 switch := NewSwitch([]Reactor{pexReactor, myReactor, ...})
79 ```