Skip to content

Commit

Permalink
fix: Re-dial peers when resuming from background on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Leblow committed Apr 12, 2024
1 parent ef0e2c6 commit ae8d202
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 0 deletions.
16 changes: 16 additions & 0 deletions packages/backend/src/backendManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,21 @@ export const runBackendMobile = async () => {
connectionsManager.closeSocket()
})

// I've noticed that two of these 'open' events can occur in quick
// succession and of course the event handlers are not awaited. This
// is a simple fix, but perhaps we can also look into the cause in
// more depth.
let openInProgress = false

rn_bridge.channel.on('open', async (msg: OpenServices) => {
log('Received "open" event via React Native Bridge')

if (openInProgress) {
log('"open" event already being processed, ignoring')
return
}
openInProgress = true

const connectionsManager = app.get<ConnectionsManagerService>(ConnectionsManagerService)
const torControl = app.get<TorControl>(TorControl)
const proxyAgent = app.get<{ proxy: { port: string } }>(SOCKS_PROXY_AGENT)
Expand All @@ -124,6 +138,8 @@ export const runBackendMobile = async () => {
proxyAgent.proxy.port = msg.httpTunnelPort

await connectionsManager.openSocket()

openInProgress = false
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,11 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI
// This method is only used on iOS through rn-bridge for reacting on lifecycle changes
public async openSocket() {
await this.socketService.init()
await this.libp2pService?.redialPeers()

// Tried to restart libp2p as another alternative, but received this:
// Error: Handler already registered for protocol /meshsub/1.1.0
await this.libp2pService?.restart()
}

public async leaveCommunity() {
Expand Down
34 changes: 34 additions & 0 deletions packages/backend/src/nest/libp2p/libp2p.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class Libp2pService extends EventEmitter {
public connectedPeers: Map<string, number> = new Map()
public dialedPeers: Set<string> = new Set()
private readonly logger = Logger(Libp2pService.name)

constructor(
@Inject(SERVER_IO_PROVIDER) public readonly serverIoProvider: ServerIoProviderTypes,
@Inject(SOCKS_PROXY_AGENT) public readonly socksProxyAgent: Agent,
Expand All @@ -40,14 +41,47 @@ export class Libp2pService extends EventEmitter {
super()
}

public restart = async () => {
await this.libp2pInstance?.stop()
await this.libp2pInstance?.start()
}

private dialPeer = async (peerAddress: string) => {
if (this.dialedPeers.has(peerAddress)) {
return
}
this.dialedPeers.add(peerAddress)
console.log('Dialing peer:', peerAddress, this.dialedPeers)
await this.libp2pInstance?.dial(multiaddr(peerAddress))
}

private hangUpPeer = async (peerAddress: string) => {
this.logger('Hanging up on peer:', peerAddress)
await this.libp2pInstance?.hangUp(multiaddr(peerAddress))
this.dialedPeers.delete(peerAddress)
}

/**
* Hang up existing peer connections and re-dial them. Specifically useful on
* iOS where Tor receives a new port when the app resumes from background and
* we want to close/re-open connections.
*/
public redialPeers = async () => {
this.logger('Re-dialing peers')

// TODO: Sort peers
const dialedPeers = Array.from(this.dialedPeers)

for (const peerAddress of dialedPeers) {
await this.hangUpPeer(peerAddress)
}

console.log('DIALED PEERS', dialedPeers, this.dialedPeers)

this.processInChunksService.updateData(dialedPeers)
await this.processInChunksService.process()
}

public readonly createLibp2pAddress = (address: string, peerId: string): string => {
return createLibp2pAddress(address, peerId)
}
Expand Down

0 comments on commit ae8d202

Please sign in to comment.