Hi, I'm trying to build w3 chat messenger using go-libp2p and react-native, I have overcome a lot of compatibility issues but there is something very annoying. in the mobile world for saving battery, the process manager may halt, stop, or kill the libp2p, and the network itself is not as stable as a normal node. my problem is libp2p receives the disconnected signal but still keeps the peer looking online and sometimes it opens the stream to a dead node (especially when using a transient connection). here is my test:
type DisconnectAbleHost interface {
host.Host
ON(t *testing.T)
OFF()
}
func NewDisconnectAbleHost(t *testing.T) DisconnectAbleHost {
identity, err := entity.CreateIdentity("")
if err != nil {
panic("")
}
sk, err := identity.DecodePrivateKey("passphrase todo!")
if err != nil {
panic("")
}
opt := swarmt.OptPeerPrivateKey(sk)
netw := swarmt.GenSwarm(t, opt)
h := bhost.NewBlankHost(netw)
h.Addrs()
return &disconnectAbleHost{h, identity, h.Addrs()}
}
type disconnectAbleHost struct {
host.Host
id entity.Identity
adders []ma.Multiaddr
}
func (d *disconnectAbleHost) ON(t *testing.T) {
d.Close()
sk, err := d.id.DecodePrivateKey("passphrase todo!")
if err != nil {
panic("")
}
opt := swarmt.OptPeerPrivateKey(sk)
netw := swarmt.GenSwarm(t, opt)
netw.ListenClose(netw.ListenAddresses()...)
netw.Listen(d.adders...)
h := bhost.NewBlankHost(netw)
d = &disconnectAbleHost{h, d.id, d.adders}
}
func (d *disconnectAbleHost) OFF() {
err := d.Network().Close()
if err != nil {
panic("can not off")
}
err = d.Close()
if err != nil {
panic("can not off")
}
}
func getNetHosts(t *testing.T, n int) []DisconnectAbleHost {
var out []DisconnectAbleHost
for i := 0; i < n; i++ {
h := NewDisconnectAbleHost(t)
t.Cleanup(func() { h.Close() })
out = append(out, h)
}
return out
}
func TestWithoutConnector(t *testing.T) {
t.Log("start test")
err := logging.SetLogLevel("msgr-core", "DEBUG")
require.NoError(t, err)
// err = logging.SetLogLevel("*", "DEBUG")
require.NoError(t, err)
hosts := getNetHosts(t, 5)
primary := hosts[0]
// primary.Close()
primary.Connect(context.Background(), hosts[1].Peerstore().PeerInfo(hosts[1].ID()))
primary.Connect(context.Background(), hosts[2].Peerstore().PeerInfo(hosts[2].ID()))
disconnectFor(t, 30*time.Second, hosts[2])
disconnectFor(t, 30*time.Second, hosts[1])
require.Eventually(t, func() bool { return !isConnected(primary) }, 5*time.Second, 1*time.Second)
require.Eventually(t, func() bool { return !isConnected2(primary, hosts[1].ID(), hosts[2].ID()) }, 5*time.Second, 1*time.Second)
require.Eventually(t, func() bool { return len(primary.Network().Peers()) != 2 }, 5*time.Second, 1*time.Second)
}
func disconnectFor(t *testing.T, d time.Duration, h DisconnectAbleHost) {
h.OFF()
fmt.Printf("adder : %v", h.Network().ListenAddresses())
go time.AfterFunc(d, func() {
h.ON(t)
})
}
func isConnected(h host.Host) bool {
var f bool = true
for _, con := range h.Network().Conns() {
_, err := con.NewStream(context.Background())
f = f && err == nil
}
return f
}
func isConnected2(h host.Host, ps ...peer.ID) bool {
var f bool = true
for _, p := range ps {
f = f && h.Network().Connectedness(p) == network.Connected
}
return f
}
Hi, I'm trying to build w3 chat messenger using go-libp2p and react-native, I have overcome a lot of compatibility issues but there is something very annoying. in the mobile world for saving battery, the process manager may halt, stop, or kill the libp2p, and the network itself is not as stable as a normal node. my problem is libp2p receives the disconnected signal but still keeps the peer looking online and sometimes it opens the stream to a dead node (especially when using a transient connection). here is my test:
Version Information