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.

79 lines
2.6 KiB

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