简体   繁体   中英

Multipeer Connectivity: Peer connect fails sometimes: Received an invitation response, but we never sent it an invitation. Aborting

I'm working on an app that uses MPC. Sometimes it's working, A and B client connects like a charm but sometimes connection fails, I get the weird error from MCNearbyServiceBrowser.

First of all, I initialize advertiser, browser, and session on both A and B devices.

 _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 and B have a unique ID for deciding what device should invite the other, and what device should accept the invitation (it's necessary to prevent A and B inviting each other at the same time). After they found each other, found peer MCNearbyServiceBrowser delegate called. A device has less uniqueId, and it sends invitation request.

-(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];
        }
    }
}

Accepting invitation (this called on B device):

-(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);
        }
}

Also implemented certificate handler like this (some post complaining about it, when not implemented it can cause connection problems w/o using security identity too):

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

I logged both devices, then:

  1. device A: invitation sent
  2. device B: accepting invitation
  3. device A: [MCNearbyServiceBrowser] Received an invitation response from [3362,090D4987], but we never sent it an invitation. Aborting!

Few secs after, when not connected I stop browsing peers, then start browsing again. After finding peer called I make same connection try again, re-invite peer on device B, what's accepting the invitation. The result can be the same or the connection state switches to Connected. These are the 2 options. Sometimes devices can connect in the first try or in less than 3 tries, but sometimes after many tries. Last time they could connect after about 40 abort message, it took about 15 mins when connection got established.

What I am doing wrong, why device A don't know anything about his own invitation?

An MCPeerID has a hashvalue member. You can compare them directly.

Two MCPeerID objects created using the same display name will not have the same hash value. This is to prevent name collisions.

If you want to recognize and be recognized by previously connected peers you must save and restore the actual MCPeerID objects.

Paste the following code into a playground and run it to see what I mean.

import MultipeerConnectivity

let hostName = "TestPlaygroundHostName"

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

firstPeerID.hashValue == secondPeerID.hashValue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM