如何检测与当前设备的 MCSession 的非编程断开连接?

How do I detect a non-programmatic disconnection from the MCSession of the current device?

为了避免成为XY问题,我先说明一下情况。

我正在开发一款游戏,其中多个设备可以相互连接以进行多人游戏。为此,我正在使用 Multipeer Connectivity。游戏支持2-4人同时玩

现在我需要处理一个玩家与所有其他玩家断开连接的情况。当玩家断开连接时,游戏仍应继续,除非只剩下一名玩家。但是,我希望向所有仍然连接的玩家显示一个警告,说 "XXX has disconnected" 和 "kills" 断开连接的玩家,并向断开连接的玩家显示另一个警告,说 "You disconnected" 并解雇游戏视图控制器。

玩家可以通过以下方式断开连接:

除了第一种方式之外的所有方式都无法通过编程方式控制。我目前可以像这样实现第一个:

当用户按下退出按钮时,就在调用 session.disconnect() 之后,我可以显示消息 "You disconnected"。在 sessionPeerDidChangeState 委托方法中,我可以检测到玩家已断开连接,我可以在那里显示 "XXX disconnected" 警报。

但是,我不知道如何处理其他情况。在我自己的测试中,我发现如果用户关闭屏幕,甚至不会调用 sessionPeerDidChangeState 委托方法。即使它被调用,我应该如何确定该设备是否是断开连接的设备?我需要知道这一点才能显示适当的消息并决定是否 "kill" 断开连接的玩家。

我知道这对于由 2 个对等方组成的会话是不可能的,因为无法确定 "who disconnect from whom"。无论如何,只有 1 名玩家无法继续游戏,所以如果我看到 self.session.connectedPeers 是空的,我将显示 "All other players have left" 警报并关闭游戏视图控制器。我只关心有 3 名玩家和其中 1 名玩家的情况。我应该能知道是哪个播放器掉线了,但我不知道怎么办。

假设您连接了 3 个对等点(对等点 1、对等点 2 和对等点 3)。假设对等点 3 打开飞行模式。点 1 和点 2 将收到委托调用 sessionPeerDidChangeState,点 3 已断开连接。但是点 1 和点 2 之间仍然有连接(所以两者都会有 self.session.connectedPeers == 1)。

另一方面,对等点 3 会看到对等点 1 和对等点 2 一个接一个地断开连接,self.session.connectedPeers == 0 因此对等点 3 可以假设它是失去连接的那个。

如问题中所述,如果按下主页按钮,您可以在 applicationDidEnterBackground 中断开与会话的连接。