从多对等连接中禁用 WiFi

Posted

技术标签:

【中文标题】从多对等连接中禁用 WiFi【英文标题】:Disable WiFi from Multi Peer Connectivity 【发布时间】:2014-10-09 23:53:51 【问题描述】:

我已经阅读了文档,但没有太多关于多点连接的信息,这些信息与为点连接选择可能的媒介有关。

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

【问题讨论】:

只是出于好奇,您为什么要这样做? WiFi 开启时非常有问题。似乎有一个操作系统级别的缓存层,即使它们是对等点已关闭,它似乎也能找到对等点。我与参与此作品的 Apple 工程师确认了这一点。 是的,我花了很多时间和精力来解决这个特定问题。 如果可以的话,请详细说明您的努力。想知道这是否有助于解决这个问题。 刚刚添加了一个可能有帮助的答案。 【参考方案1】:

正如@kdogisthebest 正确指出的那样,没有办法强制 Multipeer Connectivity 使用特定的网络技术,但是由于您的问题与 WiFi 的特定问题有关,这个答案详细说明了我正在做的工作来解决这个问题.

在创建MCNearybyServiceAdvertiser 时,我通过在discoveryInfo 中发送缩短的时间戳来解决WiFi 上的“幻像”对等点的问题。这里有几个警告:

1) 此解决方案假定两个设备具有相同的时间。我通过使用 ios-ntp 的修改版本作为应用的时间源来确保这一点。

2) 它还假设广告和浏览不会运行太久。我为发现阶段设置了 60 秒的长度,并且每次重新启动时我都会完全重新启动浏览器/广告商。

3) MPC 似乎不喜欢 discoveryInfo 中的太多字节,因此基于 epoch 发送 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 中的许多其他怪癖,但我认为以上内容涵盖了这个特定问题。

【讨论】:

使用时间戳摆脱phantom 对等点。你太棒了。谢谢@ChrisH 但话又说回来,时间戳的差异对我的用例来说是个问题:-/ 怎么样?只要您在成功连接后停止浏览器/广告商(没有待处理),如果您需要永久处于发现模式,则可以立即重新启动它。 我的用例在很大程度上依赖于在同一时间戳附近发现时向用户显示。【参考方案2】:

Multipeer Connectivity 无法做到这一点。 Apple 没有采取任何方法来限制与蓝牙的连接。

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

【讨论】:

以上是关于从多对等连接中禁用 WiFi的主要内容,如果未能解决你的问题,请参考以下文章

如何判断“移动网络数据”是启用还是禁用(即使通过 WiFi 连接)?

如何在手机中检查 WIFI 和 3G(数据计划)中的网络连接启用或禁用?

如何破解WiFi禁用? 我们单位设置的无线设备手机、平板,禁止连WiFi,连上就断网,有方法破解吗?

Android:如何以编程方式启用/禁用 Wifi 或 Internet 连接

Android:如何以编程方式启用/禁用 Wifi 或 Internet 连接

使用 Objective-C 在 iPhone 上禁用 WIFI