diff --git a/peer/peer.go b/peer/peer.go index 8edb59b66..7d341fab9 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -1746,10 +1746,6 @@ func (p *Peer) shouldLogWriteError(err error) bool { // goroutine. It uses a buffered channel to serialize output messages while // allowing the sender to continue running asynchronously. func (p *Peer) outHandler() { - // pingTicker is used to periodically send pings to the remote peer. - pingTicker := time.NewTicker(pingInterval) - defer pingTicker.Stop() - out: for { select { @@ -1790,14 +1786,6 @@ out: } p.sendDoneQueue <- struct{}{} - case <-pingTicker.C: - nonce, err := wire.RandomUint64() - if err != nil { - log.Errorf("Not sending ping to %s: %v", p, err) - continue - } - p.QueueMessage(wire.NewMsgPing(nonce), nil) - case <-p.quit: break out } @@ -1825,6 +1813,28 @@ cleanup: log.Tracef("Peer output handler done for %s", p) } +// pingHandler periodically pings the peer. It must be run as a goroutine. +func (p *Peer) pingHandler() { + pingTicker := time.NewTicker(pingInterval) + defer pingTicker.Stop() + +out: + for { + select { + case <-pingTicker.C: + nonce, err := wire.RandomUint64() + if err != nil { + log.Errorf("Not sending ping to %s: %v", p, err) + continue + } + p.QueueMessage(wire.NewMsgPing(nonce), nil) + + case <-p.quit: + break out + } + } +} + // QueueMessage adds the passed bitcoin message to the peer send queue. // // This function is safe for concurrent access. @@ -1952,6 +1962,7 @@ func (p *Peer) start() error { go p.inHandler() go p.queueHandler() go p.outHandler() + go p.pingHandler() // Send our verack message now that the IO processing machinery has started. p.QueueMessage(wire.NewMsgVerAck(), nil)