30

我在我的应用程序中使用 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(和文档)似乎有点稀疏,所以我假设它可以正常工作。在这种情况下,我应该如何重新连接设备?

4

7 回答 7

22

我遇到了同样的问题,这似乎与我的应用程序浏览和广告同时出现有关,并且发送/接受了两个邀请。当我停止这样做并让一个对等方推迟到另一个邀请时,设备保持连接。

在我的浏览器委托中,我正在检查已发现对等方的哈希值,displayName并且仅在我的对等方具有更高的哈希值时才发送邀请:

编辑

正如@Masa 所指出的, an 的hashNSString在 32 位和 64 位设备上会有所不同,因此compare:displayName.

- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info {

    NSLog(@"Browser found peer ID %@",peerID.displayName);       

    //displayName is created with [[NSUUID UUID] UUIDString]

    BOOL shouldInvite = ([_myPeerID.displayName compare:peerID.displayName]==NSOrderedDescending);

    if (shouldInvite){
        [browser invitePeer:peerID toSession:_session withContext:nil timeout:1.0]; 
    }
    else {
        NSLog(@"Not inviting");
    }
}

正如您所说,文档很少,所以谁知道 Apple 真正想要我们做什么,但我已经尝试过使用单个会话发送和接受邀请,并为每个接受/发送的邀请创建一个新会话,但是这个特别的做事方式给了我最大的成功。

于 2013-10-22T23:08:34.063 回答
5

对于任何感兴趣的人,我创建了MCSessionP2P,这是一个演示应用程序,它说明了MCSession. 该应用程序既在本地网络上宣传自己,又以编程方式连接到可用的对等点,从而建立一个对等网络。向@ChrisH 致敬,感谢他为邀请同行比较哈希值的技术。

于 2013-12-03T19:47:34.443 回答
4

我喜欢 ChrisH 的解决方案,它揭示了只有一个对等方应该连接到另一个对等方,而不是两者都应该连接的关键见解。相互连接尝试会导致相互断开连接(尽管与直觉相反,单边连接实际上并不是状态和通信方面的相互连接,因此可以正常工作)。

但是,我认为比一个同伴邀请更好的方法是两个同伴都邀请但只有一个同伴接受。我现在使用这个方法,效果很好,因为双方都有机会通过context邀请参数将丰富的信息传递给对方,而不是依赖foundPeer委托方法中可用的少量信息。

因此,我推荐这样的解决方案:

- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info
{
    [self invitePeer:peerID];
}

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL accept, MCSession *session))invitationHandler
{
    NSDictionary *hugePackageOfInformation = [NSKeyedUnarchiver unarchiveObjectWithData:context];
    BOOL shouldAccept = ([hugePackageOfInformation.UUID.UUIDString compare:self.user.UUID.UUIDString] == NSOrderedDescending);

    invitationHandler(shouldAccept && ![self isPeerConnected:peerID], [self openSession]);
}
于 2014-02-04T21:52:11.447 回答
3

当设备尝试同时相互连接时,我遇到了同样的问题,我不知道如何找到原因,因为我们没有任何错误MCSessionStateNotConnected

我们可以使用一些巧妙的方法来解决这个问题:在应用程序启动时将时间[[NSDate date] timeIntervalSince1970]放入 txt 记录(发现信息) 。谁先开始 - 向其他人发送邀请。

但我认为这不是正确的方法(如果应用程序同时启动,不太可能...... :))。我们需要找出原因。

于 2013-10-21T17:04:58.457 回答
2

这是我已向 Apple 报告的错误的结果。我在回答另一个问题时解释了如何解决它:为什么我的 MCSession 对等方会随机断开连接?

我没有将这些问题标记为合并,因为虽然底层错误和解决方案相同,但这两个问题描述了不同的问题。

于 2013-10-31T00:26:45.307 回答
1

保存对等方 B 的哈希值。如果未连接,则使用计时器连续检查连接状态,并尝试在每个给定时间段内重新连接。

于 2013-10-31T15:49:20.710 回答
0

根据苹果文档在使用 Multipeer Connectivity 时选择邀请者 “在 iOS 7 中,同时发送邀请会导致两个邀请都失败,从而使两个对等方无法相互通信。”</p>

但是 iOS 8 已经修复了它。

于 2017-02-24T07:45:08.237 回答