从多点连接禁用WiFi [英] Disable WiFi from Multi Peer Connectivity
问题描述
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屋!