mirror of https://github.com/status-im/go-waku.git
feat: use ping protocol to keep conn to peers alive (#27)
This commit is contained in:
parent
4133155590
commit
c44e50677c
|
@ -30,12 +30,12 @@ func main() {
|
||||||
nickFlag := flag.String("nick", "", "nickname to use in chat. will be generated if empty")
|
nickFlag := flag.String("nick", "", "nickname to use in chat. will be generated if empty")
|
||||||
fleetFlag := flag.String("fleet", "wakuv2.prod", "Select the fleet to connect to. (wakuv2.prod, wakuv2.test)")
|
fleetFlag := flag.String("fleet", "wakuv2.prod", "Select the fleet to connect to. (wakuv2.prod, wakuv2.test)")
|
||||||
contentTopicFlag := flag.String("contenttopic", DefaultContentTopic, "content topic to use for the chat")
|
contentTopicFlag := flag.String("contenttopic", DefaultContentTopic, "content topic to use for the chat")
|
||||||
nodeKeyFlag := flag.String("nodekey", "", "private key for this node. will be generated if empty")
|
nodeKeyFlag := flag.String("nodekey", "", "private key for this node. Will be generated if empty")
|
||||||
staticNodeFlag := flag.String("staticnode", "", "connects to a node. will get a random node from fleets.status.im if empty")
|
staticNodeFlag := flag.String("staticnode", "", "connects to a node. Will get a random node from fleets.status.im if empty")
|
||||||
storeNodeFlag := flag.String("storenode", "", "connects to a store node to retrieve messages. will get a random node from fleets.status.im if empty")
|
storeNodeFlag := flag.String("storenode", "", "connects to a store node to retrieve messages. Will get a random node from fleets.status.im if empty")
|
||||||
port := flag.Int("port", 0, "port. Will be random if 0")
|
port := flag.Int("port", 0, "port. Will be random if 0")
|
||||||
payloadV1Flag := flag.Bool("payloadV1", false, "use Waku v1 payload encoding/encryption. default false")
|
payloadV1Flag := flag.Bool("payloadV1", false, "use Waku v1 payload encoding/encryption. default false")
|
||||||
|
keepAliveFlag := flag.Int64("keep-alive", 300, "interval in seconds for pinging peers to keep the connection alive.")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf("0.0.0.0:%d", *port))
|
hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf("0.0.0.0:%d", *port))
|
||||||
|
@ -63,6 +63,7 @@ func main() {
|
||||||
node.WithHostAddress([]net.Addr{hostAddr}),
|
node.WithHostAddress([]net.Addr{hostAddr}),
|
||||||
node.WithWakuRelay(),
|
node.WithWakuRelay(),
|
||||||
node.WithWakuStore(false),
|
node.WithWakuStore(false),
|
||||||
|
node.WithKeepAlive((*keepAliveFlag)*time.Second),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(err)
|
fmt.Print(err)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
dssql "github.com/ipfs/go-ds-sql"
|
dssql "github.com/ipfs/go-ds-sql"
|
||||||
|
@ -65,6 +66,7 @@ var rootCmd = &cobra.Command{
|
||||||
storenode, _ := cmd.Flags().GetString("storenode")
|
storenode, _ := cmd.Flags().GetString("storenode")
|
||||||
staticnodes, _ := cmd.Flags().GetStringSlice("staticnodes")
|
staticnodes, _ := cmd.Flags().GetStringSlice("staticnodes")
|
||||||
topics, _ := cmd.Flags().GetStringSlice("topics")
|
topics, _ := cmd.Flags().GetStringSlice("topics")
|
||||||
|
keepAlive, _ := cmd.Flags().GetInt("keep-alive")
|
||||||
|
|
||||||
hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprint("0.0.0.0:", port))
|
hostAddr, _ := net.ResolveTCPAddr("tcp", fmt.Sprint("0.0.0.0:", port))
|
||||||
|
|
||||||
|
@ -72,10 +74,11 @@ var rootCmd = &cobra.Command{
|
||||||
|
|
||||||
if key == "" {
|
if key == "" {
|
||||||
key, err = randomHex(32)
|
key, err = randomHex(32)
|
||||||
checkError(err, "Could not generate random key")
|
checkError(err, "could not generate random key")
|
||||||
}
|
}
|
||||||
|
|
||||||
prvKey, err := crypto.HexToECDSA(key)
|
prvKey, err := crypto.HexToECDSA(key)
|
||||||
|
checkError(err, "error converting key into valid ecdsa key")
|
||||||
|
|
||||||
if dbPath == "" && useDB {
|
if dbPath == "" && useDB {
|
||||||
checkError(errors.New("dbpath can't be null"), "")
|
checkError(errors.New("dbpath can't be null"), "")
|
||||||
|
@ -93,6 +96,7 @@ var rootCmd = &cobra.Command{
|
||||||
nodeOpts := []node.WakuNodeOption{
|
nodeOpts := []node.WakuNodeOption{
|
||||||
node.WithPrivateKey(prvKey),
|
node.WithPrivateKey(prvKey),
|
||||||
node.WithHostAddress([]net.Addr{hostAddr}),
|
node.WithHostAddress([]net.Addr{hostAddr}),
|
||||||
|
node.WithKeepAlive(time.Duration(keepAlive) * time.Second),
|
||||||
}
|
}
|
||||||
|
|
||||||
if enableWs {
|
if enableWs {
|
||||||
|
@ -199,6 +203,7 @@ func init() {
|
||||||
rootCmd.Flags().Bool("use-db", true, "Store messages and peers in a DB, (default: true, use false for in-memory only)")
|
rootCmd.Flags().Bool("use-db", true, "Store messages and peers in a DB, (default: true, use false for in-memory only)")
|
||||||
rootCmd.Flags().String("dbpath", "./store.db", "Path to DB file")
|
rootCmd.Flags().String("dbpath", "./store.db", "Path to DB file")
|
||||||
rootCmd.Flags().String("storenode", "", "Multiaddr of peer to connect with for waku store protocol")
|
rootCmd.Flags().String("storenode", "", "Multiaddr of peer to connect with for waku store protocol")
|
||||||
|
rootCmd.Flags().Int("keep-alive", 300, "interval in seconds for pinging peers to keep the connection alive.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
|
"github.com/libp2p/go-libp2p/p2p/protocol/ping"
|
||||||
ma "github.com/multiformats/go-multiaddr"
|
ma "github.com/multiformats/go-multiaddr"
|
||||||
|
|
||||||
"github.com/status-im/go-waku/waku/v2/protocol"
|
"github.com/status-im/go-waku/waku/v2/protocol"
|
||||||
|
@ -38,6 +39,8 @@ type WakuNode struct {
|
||||||
filter *filter.WakuFilter
|
filter *filter.WakuFilter
|
||||||
lightPush *lightpush.WakuLightPush
|
lightPush *lightpush.WakuLightPush
|
||||||
|
|
||||||
|
ping *ping.PingService
|
||||||
|
|
||||||
subscriptions map[relay.Topic][]*Subscription
|
subscriptions map[relay.Topic][]*Subscription
|
||||||
subscriptionsMutex sync.Mutex
|
subscriptionsMutex sync.Mutex
|
||||||
|
|
||||||
|
@ -47,6 +50,7 @@ type WakuNode struct {
|
||||||
|
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
quit chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx context.Context, opts ...WakuNodeOption) (*WakuNode, error) {
|
func New(ctx context.Context, opts ...WakuNodeOption) (*WakuNode, error) {
|
||||||
|
@ -84,6 +88,7 @@ func New(ctx context.Context, opts ...WakuNodeOption) (*WakuNode, error) {
|
||||||
w.ctx = ctx
|
w.ctx = ctx
|
||||||
w.subscriptions = make(map[relay.Topic][]*Subscription)
|
w.subscriptions = make(map[relay.Topic][]*Subscription)
|
||||||
w.opts = params
|
w.opts = params
|
||||||
|
w.quit = make(chan struct{})
|
||||||
|
|
||||||
if params.enableRelay {
|
if params.enableRelay {
|
||||||
err := w.mountRelay(params.wOpts...)
|
err := w.mountRelay(params.wOpts...)
|
||||||
|
@ -111,6 +116,10 @@ func New(ctx context.Context, opts ...WakuNodeOption) (*WakuNode, error) {
|
||||||
w.mountLightPush()
|
w.mountLightPush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.keepAliveInterval > time.Duration(0) {
|
||||||
|
w.startKeepAlive(params.keepAliveInterval)
|
||||||
|
}
|
||||||
|
|
||||||
for _, addr := range w.ListenAddresses() {
|
for _, addr := range w.ListenAddresses() {
|
||||||
log.Info("Listening on ", addr)
|
log.Info("Listening on ", addr)
|
||||||
}
|
}
|
||||||
|
@ -123,6 +132,8 @@ func (w *WakuNode) Stop() {
|
||||||
defer w.subscriptionsMutex.Unlock()
|
defer w.subscriptionsMutex.Unlock()
|
||||||
defer w.cancel()
|
defer w.cancel()
|
||||||
|
|
||||||
|
close(w.quit)
|
||||||
|
|
||||||
for _, topic := range w.relay.Topics() {
|
for _, topic := range w.relay.Topics() {
|
||||||
for _, sub := range w.subscriptions[topic] {
|
for _, sub := range w.subscriptions[topic] {
|
||||||
sub.Unsubscribe()
|
sub.Unsubscribe()
|
||||||
|
@ -495,3 +506,25 @@ func (w *WakuNode) ClosePeerById(id peer.ID) error {
|
||||||
func (w *WakuNode) PeerCount() int {
|
func (w *WakuNode) PeerCount() int {
|
||||||
return len(w.host.Network().Peers())
|
return len(w.host.Network().Peers())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WakuNode) startKeepAlive(t time.Duration) {
|
||||||
|
log.Info("Setting up ping protocol with duration of", t)
|
||||||
|
|
||||||
|
w.ping = ping.NewPingService(w.host)
|
||||||
|
ticker := time.NewTicker(t)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
for _, peer := range w.host.Network().Peers() {
|
||||||
|
log.Info("Pinging", peer)
|
||||||
|
w.ping.Ping(w.ctx, peer)
|
||||||
|
}
|
||||||
|
case <-w.quit:
|
||||||
|
ticker.Stop()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package node
|
||||||
import (
|
import (
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
connmgr "github.com/libp2p/go-libp2p-connmgr"
|
connmgr "github.com/libp2p/go-libp2p-connmgr"
|
||||||
|
@ -28,6 +29,8 @@ type WakuNodeParameters struct {
|
||||||
store *store.WakuStore
|
store *store.WakuStore
|
||||||
filter *filter.WakuFilter
|
filter *filter.WakuFilter
|
||||||
|
|
||||||
|
keepAliveInterval time.Duration
|
||||||
|
|
||||||
enableLightPush bool
|
enableLightPush bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +133,13 @@ func WithLightPush() WakuNodeOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WithKeepAlive(t time.Duration) WakuNodeOption {
|
||||||
|
return func(params *WakuNodeParameters) error {
|
||||||
|
params.keepAliveInterval = t
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Default options used in the libp2p node
|
// Default options used in the libp2p node
|
||||||
var DefaultLibP2POptions = []libp2p.Option{
|
var DefaultLibP2POptions = []libp2p.Option{
|
||||||
libp2p.DefaultTransports,
|
libp2p.DefaultTransports,
|
||||||
|
|
Loading…
Reference in New Issue