4

Итак, у меня есть весь связанный с подключением мультиядерный код в основном потоке. У меня есть MCSession, MCNearbyServiceAdvertiser, and a MCNearbyServiceBrowser. Все они созданы с помощью peerID, и я уверен, что отправляет только одно приглашение.Почему соединение Multipeer настолько медленное?

Сессия становится связанной. Мои проблемы в том, что два клиента берут около 20-30 секунд для подключения. Это неприемлемо. Клиенты находятся на хорошем Wifi и bluetooth. Я хочу, чтобы просмотр, приглашение и подключение выполнялись в течение 1 секунды. Кто-нибудь знает, что замедляет работу?

Кодекс точно так, как предусмотрено здесь, и я также осуществил certificateHandler(YES)

@interface SessionController() // Class extension 
@property (nonatomic, strong) MCPeerID *peerID; 
@property (nonatomic, strong) MCSession *session; 
@property (nonatomic, strong) MCNearbyServiceAdvertiser *serviceAdvertiser; 
@property (nonatomic, strong) MCNearbyServiceBrowser *serviceBrowser; 

// Connected peers are stored in the MCSession 
// Manually track connecting and disconnected peers 
@property (nonatomic, strong) NSMutableOrderedSet *connectingPeersOrderedSet; 
@property (nonatomic, strong) NSMutableOrderedSet *disconnectedPeersOrderedSet; 
@end 

@implementation SessionController 

static NSString * const kMCSessionServiceType = @"mcsessionp2p"; 

#pragma mark - Initializer 

- (instancetype)init 
{ 
    self = [super init]; 

    if (self) 
    { 
     _peerID = [[MCPeerID alloc] initWithDisplayName:[[UIDevice currentDevice] name]]; 

     _connectingPeersOrderedSet = [[NSMutableOrderedSet alloc] init]; 
     _disconnectedPeersOrderedSet = [[NSMutableOrderedSet alloc] init]; 

     NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; 

     // Register for notifications 
     [defaultCenter addObserver:self 
          selector:@selector(startServices) 
           name:UIApplicationWillEnterForegroundNotification 
          object:nil]; 

     [defaultCenter addObserver:self 
          selector:@selector(stopServices) 
           name:UIApplicationDidEnterBackgroundNotification 
          object:nil]; 

     [self startServices]; 

     _displayName = self.session.myPeerID.displayName; 
    } 

    return self; 
} 

#pragma mark - Memory management 

- (void)dealloc 
{ 
    // Unregister for notifications on deallocation. 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 

    // Nil out delegates 
    _session.delegate = nil; 
    _serviceAdvertiser.delegate = nil; 
    _serviceBrowser.delegate = nil; 
} 

#pragma mark - Override property accessors 

- (NSArray *)connectedPeers 
{ 
    return self.session.connectedPeers; 
} 

- (NSArray *)connectingPeers 
{ 
    return [self.connectingPeersOrderedSet array]; 
} 

- (NSArray *)disconnectedPeers 
{ 
    return [self.disconnectedPeersOrderedSet array]; 
} 

#pragma mark - Private methods 

- (void)setupSession 
{ 
    // Create the session that peers will be invited/join into. 
    _session = [[MCSession alloc] initWithPeer:self.peerID]; 
    self.session.delegate = self; 

    // Create the service advertiser 
    _serviceAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.peerID 
                  discoveryInfo:nil 
                  serviceType:kMCSessionServiceType]; 
    self.serviceAdvertiser.delegate = self; 

    // Create the service browser 
    _serviceBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.peerID 
                 serviceType:kMCSessionServiceType]; 
    self.serviceBrowser.delegate = self; 
} 

- (void)teardownSession 
{ 
    [self.session disconnect]; 
    [self.connectingPeersOrderedSet removeAllObjects]; 
    [self.disconnectedPeersOrderedSet removeAllObjects]; 
} 

- (void)startServices 
{ 
    [self setupSession]; 
    [self.serviceAdvertiser startAdvertisingPeer]; 
    [self.serviceBrowser startBrowsingForPeers]; 
} 

- (void)stopServices 
{ 
    [self.serviceBrowser stopBrowsingForPeers]; 
    [self.serviceAdvertiser stopAdvertisingPeer]; 
    [self teardownSession]; 
} 

- (void)updateDelegate 
{  
    [self.delegate sessionDidChangeState]; 
} 

- (NSString *)stringForPeerConnectionState:(MCSessionState)state 
{ 
    switch (state) { 
     case MCSessionStateConnected: 
      return @"Connected"; 

     case MCSessionStateConnecting: 
      return @"Connecting"; 

     case MCSessionStateNotConnected: 
      return @"Not Connected"; 
    } 
} 

#pragma mark - MCSessionDelegate protocol conformance 

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state 
{ 
    NSLog(@"Peer [%@] changed state to %@", peerID.displayName, [self stringForPeerConnectionState:state]); 

    switch (state) 
    { 
     case MCSessionStateConnecting: 
     { 
      [self.connectingPeersOrderedSet addObject:peerID]; 
      [self.disconnectedPeersOrderedSet removeObject:peerID]; 
      break; 
     } 

     case MCSessionStateConnected: 
     { 
      [self.connectingPeersOrderedSet removeObject:peerID]; 
      [self.disconnectedPeersOrderedSet removeObject:peerID]; 
      break; 
     } 

     case MCSessionStateNotConnected: 
     { 
      [self.connectingPeersOrderedSet removeObject:peerID]; 
      [self.disconnectedPeersOrderedSet addObject:peerID]; 
      break; 
     } 
    } 

    [self updateDelegate]; 
} 

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID 
{ 
    // Decode the incoming data to a UTF8 encoded string 
    NSString *receivedMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    NSLog(@"didReceiveData %@ from %@", receivedMessage, peerID.displayName); 
} 

- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress 
{ 
    NSLog(@"didStartReceivingResourceWithName [%@] from %@ with progress [%@]", resourceName, peerID.displayName, progress); 
} 

- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error 
{ 
    NSLog(@"didFinishReceivingResourceWithName [%@] from %@", resourceName, peerID.displayName); 

    // If error is not nil something went wrong 
    if (error) 
    { 
     NSLog(@"Error [%@] receiving resource from %@ ", [error localizedDescription], peerID.displayName); 
    } 
    else 
    { 
     // No error so this is a completed transfer. The resources is located in a temporary location and should be copied to a permenant location immediately. 
     // Write to documents directory 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *copyPath = [NSString stringWithFormat:@"%@/%@", [paths firstObject], resourceName]; 
     if (![[NSFileManager defaultManager] copyItemAtPath:[localURL path] toPath:copyPath error:nil]) 
     { 
      NSLog(@"Error copying resource to documents directory"); 
     } 
     else 
     { 
      // Get a URL for the path we just copied the resource to 
      NSURL *url = [NSURL fileURLWithPath:copyPath]; 
      NSLog(@"url = %@", url); 
     } 
    } 
} 

// Streaming API not utilized in this sample code 
- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID 
{ 
    NSLog(@"didReceiveStream %@ from %@", streamName, peerID.displayName); 
} 

#pragma mark - MCNearbyServiceBrowserDelegate protocol conformance 

// Found a nearby advertising peer 
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info 
{ 
    NSString *remotePeerName = peerID.displayName; 

    NSLog(@"Browser found %@", remotePeerName); 

    MCPeerID *myPeerID = self.session.myPeerID; 

    BOOL shouldInvite = ([myPeerID.displayName compare:remotePeerName] == NSOrderedDescending); 

    if (shouldInvite) 
    { 
     NSLog(@"Inviting %@", remotePeerName); 
     [browser invitePeer:peerID toSession:self.session withContext:nil timeout:30.0]; 
    } 
    else 
    { 
     NSLog(@"Not inviting %@", remotePeerName); 
    } 

    [self updateDelegate]; 
} 

- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID 
{ 
    NSLog(@"lostPeer %@", peerID.displayName); 

    [self.connectingPeersOrderedSet removeObject:peerID]; 
    [self.disconnectedPeersOrderedSet addObject:peerID]; 

    [self updateDelegate]; 
} 

- (void)browser:(MCNearbyServiceBrowser *)browser didNotStartBrowsingForPeers:(NSError *)error 
{ 
    NSLog(@"didNotStartBrowsingForPeers: %@", error); 
} 

#pragma mark - MCNearbyServiceAdvertiserDelegate protocol conformance 

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler 
{ 
    NSLog(@"didReceiveInvitationFromPeer %@", peerID.displayName); 

    invitationHandler(YES, self.session); 

    [self.connectingPeersOrderedSet addObject:peerID]; 
    [self.disconnectedPeersOrderedSet removeObject:peerID]; 

    [self updateDelegate]; 
} 

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didNotStartAdvertisingPeer:(NSError *)error 
{ 
    NSLog(@"didNotStartAdvertisingForPeers: %@", error); 
} 

@end 
+0

Являются ли клиенты как на одном и том же WiFi? Я заметил, что если они представляют собой разные сети, для их подключения требуется много времени. – ChrisH

+0

Они оба на Wi-Fi, Bluetooth. Я также попробовал только один носитель. Это то же самое – Legolas

+0

Но когда они на WiFi, это одна и та же сеть? Я могу воспроизвести задержку в 20 секунд, когда я ставлю один на 5 ГГц, а другой на 2,4 ГГц. – ChrisH

ответ

-1

Я заметил этот вопрос и я не могу понять, Что происходит здесь, он появляется при отладке, что существует огромная задержка между уведомлением об изменении состояния, которое может быть запущено, возможно, что-то связано с самим представлением.

Обновление: Ну я думаю, что я понял вопросы после немного чтения, ответ почти мгновенно в настоящее время, в уведомлении в представлении я подтолкнул процесс обратно в основной поток, как так:

-(void)peerDidChangeStateWithNotification:(NSNotification *)notification{ 

     MCPeerID *peerID = [[notification userInfo] objectForKey:@"peerID"]; 
     NSString *peerDisplayName = peerID.displayName; 
     MCSessionState state = [[[notification userInfo] objectForKey:@"state"] intValue]; 

     if (state != MCSessionStateConnecting) { 

      if (state == MCSessionStateConnected) { 
       // add the user 
       [arrConnectedDevices addObject:peerDisplayName]; 
      } 
      else if (state == MCSessionStateNotConnected){ 

       // do we have connections 
       if ([arrConnectedDevices count] > 0) { 
        int indexOfPeer = [arrConnectedDevices indexOfObject:peerDisplayName]; 
        [arrConnectedDevices removeObjectAtIndex:indexOfPeer]; 
       } 
      } 
     } 

    // push to main queue for speedy response 
    dispatch_async(dispatch_get_main_queue(), ^(void) { 

     [collView reloadData]; 

     BOOL peersExist = ([[appDelegate.mcManager.session connectedPeers] count] == 0); 
     NSLog(@"PEER COUNT IS %lu",(unsigned long)[[appDelegate.mcManager.session connectedPeers] count]); 
     [disconnectButton setEnabled:!peersExist]; 

     if ([disconnectButton isEnabled]) { 
      [disconnectButton setBackgroundColor:[UIColor colorWithRed:(51/255.0) green:(202/255.0) blue:(168/255.0) alpha:1.0]]; 
     } 
     else{ 
      [disconnectButton setBackgroundColor:[UIColor colorWithRed:(107/255.0) green:(107/255.0) blue:(107/255.0) alpha:1.0]]; 
     } 

    }); 

} 

Надеюсь, это поможет любому, кто столкнулся с проблемами.

+0

Привет, это очень тривиально. Все, что требуется для быстрого изменения ui, должно быть отправлено на основной поток. Мой вопрос касается другой проблемы. Во всяком случае, я нашел решение. Я отправлю сюда в ближайшее время. – Legolas

+0

Legolas - не могли бы вы предоставить обновления здесь? – Shreyas

+0

@ Legolas Мне тоже будет интересно ваше решение. – berliner

Смежные вопросы