多重连接框架 - 丢失的对等体停留在会话中

Arj*_*hta 13 session ios multipeer-connectivity

我想知道这个Multipeer Connectivity框架是否可以在现实世界中使用,考虑到社区遇到的所有错误.我认为我的设置正确,但我尝试过的所有其他示例项目都遇到了类似的问题.

我遇到的问题可能与Bonjour固有的某些问题有关,我无法弄清楚,但基本上问题如下:

  • MCSession和很多同行都很活跃.
  • 现在,如果设备在会话中,然后强制退出,则"Peer"将无限期地保持连接状态.
  • 即使browser:lostPeer:为该对等方调用该方法并且不再在浏览器中显示为"附近" ,我也无法强制该用户离开.
  • session:peer:didChangeState:不为该对等方调用该方法.
  • 当强制退出的同伴回到应用程序时,它们再次被"发现",browser:foundPeer:withDiscoveryInfo:但仍然存在于session.connectedPeersNSArray中.显然,他们仍然没有收到有关会话的任何数据或更新,实际上并没有连接.
  • 似乎唯一能够将原始对等体注册MCSessionStateNotConnected到会话的方法是将该对等体重新连接到原始会话.然后session:peer:didChangeState:对peerID的新实例所在的位置进行重复调用,并且在peerID MCSessionStateConnected的旧实例调用之后不久MCSessionStateNotConnected.

示例聊天应用程序很好地演示了这个问题:https://developer.apple.com/library/ios/samplecode/MultipeerGroupChat/Introduction/Intro.html

由于似乎没有任何方法可以手动强制从会话中删除对等体,我该怎么办?我应该尝试以某种方式重建会话吗?

这个框架看起来有点混乱,但我试图保留判断力!

Chr*_*isH 8

我对此类问题的唯一解决方法是在会话和同行之间建立1-1关系.它使广播的发送变得复杂,但至少允许通过断开/删除会话本身来进行对等级断开连接和清除.

更新

为了详细说明我的原始答案,为了能够向连接的对等体发送数据,必须维护对为每个对等体创建的会话的引用.我一直在使用一个可变字典.

使用新会话发送/接受邀请后,使用MCSession委托方法更新字典:

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state {

    if (state==MCSessionStateConnected){

        _myPeerSessions[peerID.displayName] = session;

    }
    else if (state==MCSessionStateNotConnected){

        //This is where the session can be disconnected without
        //affecting other peers
        [session disconnect];            

        [_myPeerSessions removeObjectForKey:peerID.displayName];
    }
}
Run Code Online (Sandbox Code Playgroud)

可以使用返回字典的所有值的方法访问所有对等体,并且依次connectedPeers为每个对象访问所有值(在这种情况下为1)MCSession:

- (NSArray *)allConnectedPeers {

   return [[_myPeerSessions allValues] valueForKey:@"connectedPeers"];

}
Run Code Online (Sandbox Code Playgroud)

可以使用以下方法将数据发送到特定对等体或通过广播:

- (void)sendData:(NSData *)data toPeerIDs:(NSArray *)remotePeers reliable:(BOOL)reliable error:(NSError *__autoreleasing *)error {

    MCSessionSendDataMode mode = (reliable) ? MCSessionSendDataReliable : MCSessionSendDataUnreliable;

    for (MCPeerID *peer in remotePeers){

       NSError __autoreleasing *currentError = nil;

       MCSession *session = _myPeerSessions[peer.displayName];
       [session sendData:data toPeers:session.connectedPeers withMode:mode error:currentError];

       if (currentError && !error)
        *error = *currentError;
    }
}
Run Code Online (Sandbox Code Playgroud)