从多对等连接禁用WiFi

问题描述:

我已经阅读了文档,但没有太多关于Multipeer连接性的信息,这些信息与为对等连接选择可能的媒介相关。从多对等连接禁用WiFi

Multipeer Connectivity会根据WiFi或蓝牙自动发现对等点。有没有办法限制这只有蓝牙?

+0

只是出于好奇,你为什么要? – ChrisH 2014-10-10 03:24:03

+1

这是非常错误的WiFi上。似乎有一个操作系统级别的缓存层,即使在关闭对等设备时也可以找到对等设备。我与来自Apple的一位工程师证实了这一点,他在这件作品上工作。 – Legolas 2014-10-10 18:43:00

+0

是的,我花了很多时间和精力来解决这个问题。 – ChrisH 2014-10-10 18:51:00

这对Multipeer连接不可行。苹果公司没有采取任何方法来限制与蓝牙的连接。

一个答案在这里:Multipeer connectivity over Bluetooth?指出“没有明确的蓝牙或Wifi设置,它将以任何可能的方式连接设备。”

由于@ kdogisthebest正确地指出,没有办法强制Multipeer Connectivity使用特定的网络技术,但由于您的问题涉及WiFi的特定问题,因此此答案详细介绍了我正在做的工作。

我在创建MCNearybyServiceAdvertiser时,通过在discoveryInfo中发送缩短的时间戳,在WiFi上解决了'幻像'对等问题。这里有几个注意事项:

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(或者使用NTP框架或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 2014-10-13 21:06:47

+0

但是再次,时间戳的差异对我的用例来说是一个问题: -/ – Legolas 2014-10-13 21:21:00

+0

如何?只要您在连接成功后停止浏览器/广告客户(没有任何挂起),您可以立即重新启动它,如果您需要永久处于发现模式。 – ChrisH 2014-10-14 16:16:57