iosswiftmultipeer-connectivity

How can I detect the disconnection of a peer more quickly?


I am making a turn-based multiplayer game using the Multipeer Connectivity framework.

When a peer disconnects for whatever reason, I want that player to be replaced by an AI. This way the game can continue for the rest of the players.

To do this, I obviously need to detect when a player has disconnected. I know that I can do this by implementing session(_ :peer:didChange:) in the MCSessionDelegate:

func session(_ session: MCSession, peer peerID: MCPeerID, didChange state: MCSessionState) {        
    if state == .notConnected {
        // someone has disconnected, handle this...
    }
}

The problem is, this method is only called a while (a few seconds) after the player actually disconnected.

Having the other players wait for a few seconds seems like bad UX to me, so I want the session(_ :peer:didChange:) method to be called as soon as possible.

I know I can send a signal in viewDidDisappear to all connected peers, signalling that this player has quit the game. But this only handles one situation - when viewDidDisappear is called. There are lots of other ways of disconnecting from a game, such as moving outside of the bluetooth range, turning on airplane mode, or even their app crashing.


Solution

  • Well, at the end of the day the network layer is involved and there can be some delays. You won't have any influence on the method session(_ :peer:didChange:).

    In my opinion you can only send one regular ping and if this does return longer than expected, the app assumes that the connection is dead. Of course, this can lead to false positives. So the app thinks the connection is dead, but the connection to the client is still active. The app must then be able to handle this.