code: func (p *pingPongService) Run(peer *p2p.Peer, rw p2p.MsgReadWriter) error {
  	log := p.log.New("peer.id", peer.ID())
  
  	errC := make(chan error)
  	go func() {
  		for range time.Tick(10 * time.Second) {
  			log.Info("sending ping")
  			if err := p2p.Send(rw, pingMsgCode, "PING"); err != nil {
  				errC <- err
  				return
  			}
  		}
  	}()
  	go func() {
  		for {
  			msg, err := rw.ReadMsg()
  			if err != nil {
  				errC <- err
  				return
  			}
  			payload, err := ioutil.ReadAll(msg.Payload)
  			if err != nil {
  				errC <- err
  				return
  			}
  			log.Info("received message", "msg.code", msg.Code, "msg.payload", string(payload))
  			atomic.AddInt64(&p.received, 1)
  			if msg.Code == pingMsgCode {
  				log.Info("sending pong")
  				go p2p.Send(rw, pongMsgCode, "PONG")
  			}
  		}
  	}()
  	return <-errC
  }
docs: // Run implements the ping-pong protocol which sends ping messages to the peer
  // at 10s intervals, and responds to pings with pong messages.