多重连接:对等连接有时失败:收到邀请响应,但我们从未向其发送过邀请。中止

时间:2016-12-07 10:46:22

标签: ios

我正在开发一款使用MPC的应用。有时它正在工作,A和B客户端像魅力连接,但有时连接失败,我从MCNearbyServiceBrowser得到奇怪的错误。

首先,我在A和B设备上初始化广告客户,浏览器和会话。

 _peerID = [[MCPeerID alloc] initWithDisplayName:uniqueId];
 session = [[MCSession alloc] initWithPeer:_peerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
 session.delegate = self;

 NSDictionary *dict = @{@“uniqueId” : uniqueId};
 _advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:_peerID discoveryInfo:dict  serviceType:@“my-app”];
 _advertiser.delegate = self;

 _browser = [[MCNearbyServiceBrowser alloc] initWithPeer:_peerID serviceType:@“my-app”];
 _browser.delegate = self;

 [_advertiser startAdvertisingPeer];
 [_browser startBrowsingForPeers];

A和B有一个唯一的ID用于决定哪个设备应该邀请另一个设备,以及哪个设备应该接受邀请(这是防止A和B同时互相邀请的必要条件)。他们找到对方后,发现对等的MCNearbyServiceBrowser委托调用了。设备的uniqueId较少,并发送邀请请求。

-(void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary<NSString *,NSString *> *)info {
    if (![[session connectedPeers] containsObject:peerID]) {
        NSInteger targetUniqueId = [[peerID displayName] integerValue];
        NSInteger myUniqueId = [uniqueId integerValue];

        if(myUniqueId<targetUniqueId){
          NSLog(@“invitation sent”);
          [browser invitePeer:peerID toSession:session withContext:nil timeout:inviteTimeout];
        }
    }
}

接受邀请(在B设备上调用):

-(void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession * _Nonnull))invitationHandler {
    NSInteger targetUniqueId = [[peerID displayName] integerValue];
    NSInteger myUniqueId = [uniqueId integerValue];
        if(myUniqueId>targetUniqueId){
          NSLog(@“accepting invitation”);
          invitationHandler(YES, session);
        }
}

同样实现了这样的证书处理程序(有些帖子抱怨它,如果没有实现,它也会导致连接问题而不使用安全标识):

-(void)session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL))certificateHandler {
    certificateHandler(YES);
}

我记录了两台设备,然后:

  1. 设备A:邀请已发送
  2. 设备B:接受邀请
  3. 设备A:[MCNearbyServiceBrowser]收到[3362,090D4987]的邀请回复,但我们从未向其发送过邀请。中止!
  4. 几秒后,当没有连接时,我停止浏览对等体,然后再次开始浏览。在找到名为I的同伴后,再次尝试相同的连接,重新邀请设备B上的同伴,接受邀请的是什么。结果可以相同,或者连接状态切换为已连接。这是两个选项。有时设备可以在第一次尝试或少于3次尝试时连接,但有时可以在多次尝试之后连接。上次他们可以在大约40个中止消息后连接,当连接建立时花了大约15分钟。

    我做错了什么,为什么设备A对自己的邀请一无所知?

1 个答案:

答案 0 :(得分:0)

MCPeerID具有哈希值成员。您可以直接比较它们。

使用相同显示名称创建的两个MCPeerID对象将不会具有相同的哈希值。这是为了防止名称冲突。

如果要识别先前连接的对等节点并被其识别,则必须保存并还原实际的MCPeerID对象。

将以下代码粘贴到游乐场中,然后运行它以了解我的意思。

import MultipeerConnectivity

let hostName = "TestPlaygroundHostName"

let firstPeerID = MCPeerID(displayName: hostName)
let secondPeerID = MCPeerID(displayName: hostName)

firstPeerID.hashValue == secondPeerID.hashValue