2014-10-09 2 views
1

Я просмотрел документацию, но информации о Multipeer Connectivity относительно выбора возможного носителя для подключения сверстников не так много.Отключить Wi-Fi от многоуровневого подключения

Multipeer Connectivity автоматически обнаруживает одноранговые узлы на основе WiFi или Bluetooth. Есть ли способ ограничить это только Bluetooth?

+0

Просто из любопытства, зачем вам это нужно? – ChrisH

+1

Очень плохо работает с WiFi. Кажется, что уровень кэширования уровня ОС, который, похоже, находит одноранговых узлов, даже когда они сверстники отключены. Я подтвердил это инженером из Apple, который работал над этой штукой. – Legolas

+0

Да, я потратил много времени и сил на решение этой проблемы. – ChrisH

ответ

0

Это невозможно при использовании Multipeer Connectivity. Нет никаких методов, которые Apple установит для ограничения соединения с Bluetooth.

Один ответ здесь: Multipeer connectivity over Bluetooth? гласит: «Нет явной настройки для Bluetooth или Wi-Fi, он будет подключать устройства любым возможным способом, которым они доступны».

3

Как @kdogisthebest правильно заявляет, что невозможно использовать Multipeer Connectivity для использования определенной сетевой технологии, но поскольку ваш вопрос относится к конкретной проблеме с WiFi, этот ответ детализирует то, что я делаю, чтобы обойти это.

Я работал вокруг проблемы сверстников «фантомных» через WiFi, отправив укороченную метку времени в discoveryInfo при создании MCNearybyServiceAdvertiser. Здесь есть несколько оговорок:

1) Данное решение предполагает, что оба устройства имеют одно и то же время. Я гарантирую это, используя измененную версию ios-ntp в качестве источника времени приложения.

2) Он также предполагает, что реклама и просмотр не запускаются слишком долго. У меня установленная длина 60 секунд для фаз обнаружения, и я полностью перезапускаю браузер/рекламодателя при каждом перезапуске.

3) MPC, похоже, не слишком много байтов в discoveryInfo, поэтому отправка NSTimeInterval на основе эпохи не работает. Я должен был усечь их.

Итак, когда мое приложение входит в режим обнаружения, оно начинает просмотр и рекламу одновременно. Рекламный код выглядит следующим образом:.

- (void)startAdvertising { 

    if (_advertising){ 
     NSLog(@"Already advertising"); 
     return; 
    } 

    self.acceptedPeerIDNameMap = [NSMutableDictionary dictionary]; 

    NSInteger timeStamp = [self shortenedNetworkTimeStamp]; 
    NSDictionary *discoveryInfo = @{kAdvertisingDiscoveryInfoTimestampKey:[NSString stringWithFormat:@"%ld",(long)timeStamp]}; 

    NSLog(@"Starting advertiser"); 

    self.serviceAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:_myPeerID 
                  discoveryInfo:discoveryInfo 
                  serviceType:kServiceType]; 
    _serviceAdvertiser.delegate = self; 

    [_serviceAdvertiser startAdvertisingPeer]; 

    self.advertising = YES; 
} 

метод shortenedNetworkTimestamp просто принимает NSTimeInterval (либо с использованием рамок НТПА или timeIntervalSinceReferenceDate и удалением 1400000000 из него

Затем, когда браузер обнаруживает пэр, он проверяет, является ли отметка время рекламодателя находится в пределах известной длительности открытия (в моем случае 60 секунд):

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

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

    //Only one peer should invite the other 
    BOOL shouldInvite = [peerID.displayName compare:_myPeerID.displayName]==NSOrderedAscending; 

    //Don't re-send invitations 
    if (_peerInfoDisplayNameMap[peerID.displayName]){ 
     DLog(@"Already connected to peerID %@",peerID.displayName); 
     shouldInvite = NO; 
    } 
    else if (_invitedPeerIDNameMap[peerID.displayName]){ 
      DLog(@"Already invited peerID %@",peerID.displayName); 
      shouldInvite = NO; 
    } 

    //Invite if discovery info is valid 
    if (shouldInvite && [self discoveryInfoIsValid:info]) { 

     DLog(@"Inviting"); 

     _invitedPeerIDNameMap[peerID.displayName] = peerID; 

     MCSession *session = [self availableSession]; 
     [_serviceBrowser invitePeer:peerID toSession:session withContext:nil timeout:0]; 
    } 
    else { 
     DLog(@"Not inviting"); 
    } 
} 

Инфо-открытия проверка действительности довольно проста - просто убедитесь, что метка время сена т в информации внутри диапазона времени открытия (в моем случае kDiscoveryPhaseDuration 60 секунд):

- (BOOL)discoveryInfoIsValid:(NSDictionary *)info { 

    BOOL isValid = YES; 

    NSString *infoTimeStamp = info[kAdvertisingDiscoveryInfoTimestampKey]; 
    NSTimeInterval sentTimeStamp = (infoTimeStamp) ? [infoTimeStamp doubleValue] : -1; 
    NSTimeInterval currentTimeStamp = [self shortenedNetworkTimeStamp]; 

    if (sentTimeStamp==-1 || (currentTimeStamp - sentTimeStamp) > kDiscoveryPhaseDuration){ 
     DLog(@"Expired discovery info (current=%f, sent=%f)",currentTimeStamp,sentTimeStamp); 
     isValid = NO; 
    } 

    return isValid; 
} 

Надеюсь, это поможет. В MPC есть много других причуд, которые я обрабатываю в своем собственном коде, но я думаю, что вышеупомянутое охватывает эту конкретную проблему.

+0

Использование временной метки, чтобы избавиться от «фантомных» сверстников. Ты обалденный. Спасибо @ChrisH – Legolas

+0

Но опять же, разница в метке времени является проблемой для моего варианта использования: -/ – Legolas

+0

Как это сделать? Пока вы останавливаете браузера/рекламодателя после успешного соединения (без ожидания), вы можете перезапустить его сразу, если вам нужно постоянно находиться в режиме обнаружения. – ChrisH