我正在应用中使用iOS 7 Multipeer框架,但遇到设备断开连接的问题。如果我在两台设备上打开应用:设备A和设备B这两个设备会自动相互连接。但是,几秒钟后,设备A会与设备B断开连接。例如,最初的连接如下所示:
A ---> B
A <--- B
几秒钟后:
A ---> B
A B
设备A保持其连接,但设备B获得MCSessionStateNotConnected。
这意味着A可以向B发送数据,但B不能回复。我尝试通过检查设备是否已连接来解决此问题,如果未连接,则使用以下命令重新启动连接:
[browser invitePeer:peerID toSession:_session withContext:Nil timeout:10];
但是didChangeState回调只是用MCSessionStateNotConnected调用的。
奇怪的是,如果我将应用程序A发送到后台,然后重新打开它,B重新连接到它,连接保持不变。
Multipeer API(和文档)看起来有点稀疏,所以我假设它会工作。在这种情况下,我应该如何重新连接设备?
8条答案
按热度按时间4uqofj5v1#
我也遇到了同样的问题,似乎是因为我的应用程序同时浏览和广告,以及两个邀请被发送/接受。当我停止这样做,让一个对等体服从另一个邀请时,设备仍然保持连接。
在我的浏览器代理中,我检查发现的对等体的
displayName
的哈希值,并且仅在对等体具有更高的哈希值时才发送邀请:编辑
正如@Masa所指出的,
NSString
的hash
值在32位和64位设备上是不同的,因此在displayName
上使用compare:
方法更安全。正如你所说,文档很少,所以谁知道Apple真正希望我们做什么,但我已经尝试过使用单个会话发送和接受邀请,并为每个接受/发送的邀请创建一个新会话,但这种特殊的做事方式给了我最大的成功。
u4vypkhs2#
我为感兴趣的人创建了MCSessionP2P,这是一个演示应用程序,展示了
MCSession
的ad-hoc网络特性。该应用程序既在本地网络上发布自己的广告,又通过编程连接到可用的对等点,建立了一个对等网络。@ChrisH为邀请对等点而比较哈希值的技术值得一提。iqxoj9l93#
我喜欢ChrisH的解决方案,它揭示了一个关键的观点,即 * 只有一个对等体应该连接到另一个对等体 *,而不是两个都连接。相互连接的尝试会导致相互断开(尽管并不是说单边连接实际上是,违反直觉,在状态和通信方面的相互连接,所以这样做很好)。
然而,我认为比一个对等体 inviting 更好的方法是两个对等体都邀请,但只有一个对等体 accept。我现在使用这种方法,效果很好,因为两个对等体都有机会通过邀请的
context
参数向另一个传递丰富的信息,而不必依赖foundPeer
委托方法中可用的少量信息。因此,我推荐这样一个解决方案:
uqxowvwt4#
当设备尝试同时相互连接时,我遇到了同样的问题,我不知道如何找到原因,因为我们没有任何关于 MCSessionStateNotConnected 的错误。
我们可以用一些狡猾的办法来解决这个问题:在txt文件中记录(发现信息)应用程序启动的时间 [[NSDate date] timeIntervalSince 1970]。谁先启动-向其他人发送邀请。
但我认为这不是一个正确的方式(如果应用程序在同一时间启动,不太可能...:)。我们需要找出原因。
lnlaulya5#
这是一个错误的结果,我已经向苹果报告了这个错误。我在回答另一个问题时解释了如何修复它:Why does my MCSession peer disconnect randomly?
我没有将这些问题标记为合并,因为虽然底层bug和解决方案是相同的,但这两个问题描述的是不同的问题。
mwg9r5ms6#
保存对等体B的散列。使用计时器连续检查连接的状态,如果未连接,则尝试在每个给定时间段重新连接。
3bygqnnd7#
根据苹果文件Choosing an inviter when using Multipeer Connectivity,“在iOS 7中,同时发送邀请可能会导致两个邀请都失败,使两个对等方无法相互通信。
但iOS 8已经解决了这个问题。
eqoofvh98#
It seems that the .notConnected message is a false positive in that the device is still receiving data. So, I manually updated local connection state to .connected
It was hard to factor out other state from other examples. So, I wrote a bare bones MCSession example for SwiftUI, here: MultiPeer