whisper/libp2p/ping.go

67 lines
1.4 KiB
Go

package libp2p
import (
"fmt"
"time"
"github.com/ethereum/go-ethereum/log"
net "github.com/libp2p/go-libp2p-net"
)
const (
pingproto = "/ping/0.0.1"
pingMsg byte = 1
pongMsg byte = 2
)
func makePingHandler(c connection, period, r, w time.Duration) net.StreamHandler {
return func(s net.Stream) {
defer s.Close()
ping := [1]byte{pingMsg}
pong := [1]byte{pongMsg}
received := [1]byte{}
quit := make(chan struct{})
go func() {
tick := time.NewTicker(period)
defer tick.Stop()
for {
select {
case <-quit:
return
case <-tick.C:
s.SetWriteDeadline(time.Now().Add(w))
if _, err := s.Write(ping[:]); err != nil {
log.Error("error sending the ping", "error", err)
return
}
}
}
}()
for {
received[0] = 0
s.SetReadDeadline(time.Now().Add(r))
if _, err := s.Read(received[:]); err != nil {
log.Error("error on read", "error", err)
close(quit)
s.Conn().Close()
return
}
switch received[0] {
case pingMsg:
s.SetWriteDeadline(time.Now().Add(w))
if _, err := s.Write(pong[:]); err != nil {
log.Error("error sending a pong", "error", err)
close(quit)
s.Conn().Close()
return
}
c.Update(time.Now())
case pongMsg:
c.Update(time.Now())
default:
log.Error("received unknown message", "msg", fmt.Sprintf("%x", received))
}
}
}
}