从多点连接禁用WiFi [英] Disable WiFi from Multi Peer Connectivity

查看:159
本文介绍了从多点连接禁用WiFi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



Multipeer连接自动发现了多个连接基于WiFi的对等体,或蓝牙。

解决方案

由于@kdogisthebest正确地说明,没有办法强制Multipeer连接以使用特定的网络技术,但由于您的问题涉及WiFi的特定问题,此答案详细说明了我正在做的工作。



我已经通过在 discoveryInfo 中创建 MCNearybyServiceAdvertiser 时发送一个缩短的时间戳,解决了'phantom' code>。这里有几个警告:



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



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



3)MPC似乎不喜欢 discoveryInfo 中的太多字节,因此发送基于epoch的NSTimeInterval不起作用。



所以当我的应用程序进入发现模式时,它会同时开始浏览和广告。广告代码如下:

   - (void)startAdvertising {

if(_advertising){
NSLog(@已经广告);
return;
}

self.acceptedPeerIDNameMap = [NSMutableDictionary dictionary];

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

NSLog(@开始广告客户);

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

[_serviceAdvertiser startAdvertisingPeer];

self.advertising = YES;
}

方法 simplifiedNetworkTimestamp 只需要一个NSTimeInterval(使用ntp框架或 timeIntervalSinceReferenceDate 并从中删除 1400000000



然后,当浏览器发现对等体时,它检查广告商的时间戳是否在已知发现持续时间(在我的情况下为60秒):

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

DLog发现对等体ID%@,peerID.displayName);

//只有一个对等体应该邀请其他
BOOL shouldInvite = [peerID.displayName compare:_myPeerID.displayName] == NSOrderedAscending;

//不重新发送邀请
if(_peerInfoDisplayNameMap [peerID.displayName]){
DLog(@已连接到peerID%@,peerID.displayName );
shouldInvite = NO;
}
else if(_invitedPeerIDNameMap [peerID.displayName]){
DLog(@Already invited peerID%@,peerID.displayName);
shouldInvite = NO;
}

//邀请发现信息是否有效
if(shouldInvite&& [self discoveryInfoIsValid:info]){

DLog @邀请);

_invitedPeerIDNameMap [peerID.displayName] = peerID;

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

发现信息有效性检查很简单 - 只是make确保信息中发送的时间戳在发现时间范围内(在我的情况下 kDiscoveryPhaseDuration 为60秒):

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

BOOL isValid = YES;

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

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

return isValid;
}

希望这有助于。在我自己的代码中,我正在处理的MPC中还有很多其他的怪癖,但我认为以上涵盖了这个具体的问题。


I have gone over the documentation, but there isn't much information on Multipeer Connectivity related to choosing a possible medium for peers to connect.

Multipeer Connectivity automatically discovers peers based on WiFi, or Bluetooth. Is there a way to limit this to only Bluetooth?

解决方案

As @kdogisthebest correctly states, there's no way to force Multipeer Connectivity to use a particular network technology, but as your question relates to a particular problem with WiFi, this answer details what I'm doing to work around that.

I've worked around the issue of 'phantom' peers over WiFi by sending a shortened timestamp in the discoveryInfo when creating the MCNearybyServiceAdvertiser. There are several caveats here:

1) This solution assumes both devices have the same time. I ensure this by using a modified version of ios-ntp as the app's time source.

2) It also assumes that Advertising and Browsing do not run for too long. I have a set length of 60 seconds for discovery phases, and I completely re-init the browser/advertiser on each restart.

3) MPC doesn't seem to like too many bytes in the discoveryInfo so sending an NSTimeInterval based on epoch doesn't work. I had to truncate them.

So when my app enters discovery mode, it starts browsing and advertising simultaneously. The advertising code looks like:

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

The method shortenedNetworkTimestamp just takes an NSTimeInterval (either using the ntp framework or timeIntervalSinceReferenceDate and removing 1400000000 from it.

Then when the browser discovers a peer, it checks whether the advertiser's timestamp is within the known discovery duration (in my case 60 seconds):

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

The discovery info validity check is pretty simple - just make sure the timestamp sent in the info is inside of the discovery time range (in my case kDiscoveryPhaseDuration is 60 seconds):

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

Hopefully this helps. There are many other quirks in MPC that I'm handling in my own code but I think the above covers this specific problem.

这篇关于从多点连接禁用WiFi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆