因此,我在主线程中拥有所有与多个连接相关的代码。我有MCSession, MCNearbyServiceAdvertiser, and a MCNearbyServiceBrowser
。这些都是使用peerID创建的,我确保只有一个发送邀请。
会话已连接。我的问题是,两个客户需要 20-30秒才能连接。这是不可接受的。客户端有良好的Wifi和蓝牙。我希望浏览,邀请处理程序和连接在1秒内发生。有没有人知道什么减慢了什么?
代码完全按此处提供,我也实现了certificateHandler(YES)
@interface SessionController () // Class extension
@property (nonatomic, strong) MCPeerID *peerID;
@property (nonatomic, strong) MCSession *session;
@property (nonatomic, strong) MCNearbyServiceAdvertiser *serviceAdvertiser;
@property (nonatomic, strong) MCNearbyServiceBrowser *serviceBrowser;
// Connected peers are stored in the MCSession
// Manually track connecting and disconnected peers
@property (nonatomic, strong) NSMutableOrderedSet *connectingPeersOrderedSet;
@property (nonatomic, strong) NSMutableOrderedSet *disconnectedPeersOrderedSet;
@end
@implementation SessionController
static NSString * const kMCSessionServiceType = @"mcsessionp2p";
#pragma mark - Initializer
- (instancetype)init
{
self = [super init];
if (self)
{
_peerID = [[MCPeerID alloc] initWithDisplayName:[[UIDevice currentDevice] name]];
_connectingPeersOrderedSet = [[NSMutableOrderedSet alloc] init];
_disconnectedPeersOrderedSet = [[NSMutableOrderedSet alloc] init];
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
// Register for notifications
[defaultCenter addObserver:self
selector:@selector(startServices)
name:UIApplicationWillEnterForegroundNotification
object:nil];
[defaultCenter addObserver:self
selector:@selector(stopServices)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
[self startServices];
_displayName = self.session.myPeerID.displayName;
}
return self;
}
#pragma mark - Memory management
- (void)dealloc
{
// Unregister for notifications on deallocation.
[[NSNotificationCenter defaultCenter] removeObserver:self];
// Nil out delegates
_session.delegate = nil;
_serviceAdvertiser.delegate = nil;
_serviceBrowser.delegate = nil;
}
#pragma mark - Override property accessors
- (NSArray *)connectedPeers
{
return self.session.connectedPeers;
}
- (NSArray *)connectingPeers
{
return [self.connectingPeersOrderedSet array];
}
- (NSArray *)disconnectedPeers
{
return [self.disconnectedPeersOrderedSet array];
}
#pragma mark - Private methods
- (void)setupSession
{
// Create the session that peers will be invited/join into.
_session = [[MCSession alloc] initWithPeer:self.peerID];
self.session.delegate = self;
// Create the service advertiser
_serviceAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.peerID
discoveryInfo:nil
serviceType:kMCSessionServiceType];
self.serviceAdvertiser.delegate = self;
// Create the service browser
_serviceBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.peerID
serviceType:kMCSessionServiceType];
self.serviceBrowser.delegate = self;
}
- (void)teardownSession
{
[self.session disconnect];
[self.connectingPeersOrderedSet removeAllObjects];
[self.disconnectedPeersOrderedSet removeAllObjects];
}
- (void)startServices
{
[self setupSession];
[self.serviceAdvertiser startAdvertisingPeer];
[self.serviceBrowser startBrowsingForPeers];
}
- (void)stopServices
{
[self.serviceBrowser stopBrowsingForPeers];
[self.serviceAdvertiser stopAdvertisingPeer];
[self teardownSession];
}
- (void)updateDelegate
{
[self.delegate sessionDidChangeState];
}
- (NSString *)stringForPeerConnectionState:(MCSessionState)state
{
switch (state) {
case MCSessionStateConnected:
return @"Connected";
case MCSessionStateConnecting:
return @"Connecting";
case MCSessionStateNotConnected:
return @"Not Connected";
}
}
#pragma mark - MCSessionDelegate protocol conformance
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
NSLog(@"Peer [%@] changed state to %@", peerID.displayName, [self stringForPeerConnectionState:state]);
switch (state)
{
case MCSessionStateConnecting:
{
[self.connectingPeersOrderedSet addObject:peerID];
[self.disconnectedPeersOrderedSet removeObject:peerID];
break;
}
case MCSessionStateConnected:
{
[self.connectingPeersOrderedSet removeObject:peerID];
[self.disconnectedPeersOrderedSet removeObject:peerID];
break;
}
case MCSessionStateNotConnected:
{
[self.connectingPeersOrderedSet removeObject:peerID];
[self.disconnectedPeersOrderedSet addObject:peerID];
break;
}
}
[self updateDelegate];
}
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
{
// Decode the incoming data to a UTF8 encoded string
NSString *receivedMessage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"didReceiveData %@ from %@", receivedMessage, peerID.displayName);
}
- (void)session:(MCSession *)session didStartReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID withProgress:(NSProgress *)progress
{
NSLog(@"didStartReceivingResourceWithName [%@] from %@ with progress [%@]", resourceName, peerID.displayName, progress);
}
- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error
{
NSLog(@"didFinishReceivingResourceWithName [%@] from %@", resourceName, peerID.displayName);
// If error is not nil something went wrong
if (error)
{
NSLog(@"Error [%@] receiving resource from %@ ", [error localizedDescription], peerID.displayName);
}
else
{
// No error so this is a completed transfer. The resources is located in a temporary location and should be copied to a permenant location immediately.
// Write to documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *copyPath = [NSString stringWithFormat:@"%@/%@", [paths firstObject], resourceName];
if (![[NSFileManager defaultManager] copyItemAtPath:[localURL path] toPath:copyPath error:nil])
{
NSLog(@"Error copying resource to documents directory");
}
else
{
// Get a URL for the path we just copied the resource to
NSURL *url = [NSURL fileURLWithPath:copyPath];
NSLog(@"url = %@", url);
}
}
}
// Streaming API not utilized in this sample code
- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID
{
NSLog(@"didReceiveStream %@ from %@", streamName, peerID.displayName);
}
#pragma mark - MCNearbyServiceBrowserDelegate protocol conformance
// Found a nearby advertising peer
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo:(NSDictionary *)info
{
NSString *remotePeerName = peerID.displayName;
NSLog(@"Browser found %@", remotePeerName);
MCPeerID *myPeerID = self.session.myPeerID;
BOOL shouldInvite = ([myPeerID.displayName compare:remotePeerName] == NSOrderedDescending);
if (shouldInvite)
{
NSLog(@"Inviting %@", remotePeerName);
[browser invitePeer:peerID toSession:self.session withContext:nil timeout:30.0];
}
else
{
NSLog(@"Not inviting %@", remotePeerName);
}
[self updateDelegate];
}
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID
{
NSLog(@"lostPeer %@", peerID.displayName);
[self.connectingPeersOrderedSet removeObject:peerID];
[self.disconnectedPeersOrderedSet addObject:peerID];
[self updateDelegate];
}
- (void)browser:(MCNearbyServiceBrowser *)browser didNotStartBrowsingForPeers:(NSError *)error
{
NSLog(@"didNotStartBrowsingForPeers: %@", error);
}
#pragma mark - MCNearbyServiceAdvertiserDelegate protocol conformance
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
{
NSLog(@"didReceiveInvitationFromPeer %@", peerID.displayName);
invitationHandler(YES, self.session);
[self.connectingPeersOrderedSet addObject:peerID];
[self.disconnectedPeersOrderedSet removeObject:peerID];
[self updateDelegate];
}
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didNotStartAdvertisingPeer:(NSError *)error
{
NSLog(@"didNotStartAdvertisingForPeers: %@", error);
}
@end
答案 0 :(得分:-1)
我已经注意到了这个问题,而且我似乎无法弄清楚这里发生了什么,在调试时会出现状态更改被通知的通知之间存在巨大延迟,或许可以做些什么与观点本身。
更新:嗯,我认为我在阅读之后想出了问题,现在响应很快,在视图中的通知中我将进程推回主线程如下:
-(void)peerDidChangeStateWithNotification:(NSNotification *)notification{
MCPeerID *peerID = [[notification userInfo] objectForKey:@"peerID"];
NSString *peerDisplayName = peerID.displayName;
MCSessionState state = [[[notification userInfo] objectForKey:@"state"] intValue];
if (state != MCSessionStateConnecting) {
if (state == MCSessionStateConnected) {
// add the user
[arrConnectedDevices addObject:peerDisplayName];
}
else if (state == MCSessionStateNotConnected){
// do we have connections
if ([arrConnectedDevices count] > 0) {
int indexOfPeer = [arrConnectedDevices indexOfObject:peerDisplayName];
[arrConnectedDevices removeObjectAtIndex:indexOfPeer];
}
}
}
// push to main queue for speedy response
dispatch_async(dispatch_get_main_queue(), ^(void) {
[collView reloadData];
BOOL peersExist = ([[appDelegate.mcManager.session connectedPeers] count] == 0);
NSLog(@"PEER COUNT IS %lu",(unsigned long)[[appDelegate.mcManager.session connectedPeers] count]);
[disconnectButton setEnabled:!peersExist];
if ([disconnectButton isEnabled]) {
[disconnectButton setBackgroundColor:[UIColor colorWithRed:(51/255.0) green:(202/255.0) blue:(168/255.0) alpha:1.0]];
}
else{
[disconnectButton setBackgroundColor:[UIColor colorWithRed:(107/255.0) green:(107/255.0) blue:(107/255.0) alpha:1.0]];
}
});
}
希望这有助于遇到问题的任何人。