蓝牙连接立即断开多点框架
Posted
技术标签:
【中文标题】蓝牙连接立即断开多点框架【英文标题】:bluetooth connection is immediately disconnecting multipeer framework 【发布时间】:2014-06-04 05:17:07 【问题描述】:我正在尝试使用多点连接框架建立一对一的点对点连接。当我向附近的对等方发送邀请时,该设备已连接(有时需要很长时间才能连接),并且发送请求的对等方总是需要很长时间才能将其状态更改为已连接,一旦立即连接,它就会断开连接从会话。我尝试调试问题但没有发现任何问题,不知道发生了什么问题,如果我遗漏任何内容或代码中有任何错误,请告诉我。
下面给出的是相同的代码sn-p。
MPCHandler.m
#define DidChangeStateNotification @"E_DidChangeStateNotification"
#define DidReceiveDataNotification @"E_DidReceiveDataNotification"
#define DidInviteNotification @"E_DidInvitedNotification"
#define DidReceivedInvetationNotification @"E_DidReceivedInvetationNotification"
static NSString * const EServiceType = @"E-service";
@interface MPCHandler ()
@property AppDelegate *appDelegate;
@end
@implementation MPCHandler
- (void)setupPeerWithDisplayName:(NSString *)displayName
self.appDelegate = [[UIApplication sharedApplication] delegate];
self.peerID = [[MCPeerID alloc] initWithDisplayName:displayName];
self.connectedPeers = [NSMutableArray array];
self.foundPeers = [NSMutableArray array];
self.invitedPeers = [NSMutableArray array];
- (void)setupSession
self.session = [[MCSession alloc] initWithPeer:self.peerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
self.session.delegate = self;
- (void)setupBrowser
self.browser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.peerID serviceType:EServiceType];
self.browser.delegate = self;
- (void)advertiseSelf:(BOOL)advertise
if (advertise)
self.advertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.peerID discoveryInfo:nil serviceType:EServiceType];
self.advertiser.delegate = self;
[self.advertiser startAdvertisingPeer];
else
[self.advertiser stopAdvertisingPeer];
self.advertiser = nil;
#pragma MCSessionDelegate methods
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
NSDictionary *userInfo = @ @"peerID": peerID,
@"state" : @(state) ;
dispatch_async(dispatch_get_main_queue(), ^
[[NSNotificationCenter defaultCenter] postNotificationName:DidChangeStateNotification
object:nil
userInfo:userInfo];
);
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
NSDictionary *userInfo = @ @"data": data,
@"peerID": peerID ;
dispatch_async(dispatch_get_main_queue(), ^
[[NSNotificationCenter defaultCenter] postNotificationName:DidReceiveDataNotification
object:nil
userInfo:userInfo];
);
- (void)session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL))certificateHandler
certificateHandler(YES);
#pragma MCNearbyServiceAdvertiserDelegate 方法
// Incoming invitation request. Call the invitationHandler block with YES and a valid session to connect the inviting peer to the session.
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler
NSDictionary *info =[NSDictionary dictionaryWithObject:peerID.displayName forKey:@"displayName"];
NSLog(@"%@ Received Invetation from : %@",self.peerID.displayName,peerID.displayName);
invitationHandler(YES,self.session);
[self.connectedPeers addObject:peerID];
self.invited = NO;
dispatch_async(dispatch_get_main_queue(), ^
[[NSNotificationCenter defaultCenter] postNotificationName:DidReceivedInvetationNotification
object:nil
userInfo:info];
);
#pragma MCNearbyServiceBrowserDelegate 方法
// Found a nearby advertising peer
- (void)browser:(MCNearbyServiceBrowser *)browser foundPeer:(MCPeerID *)peerID withDiscoveryInfo: (NSDictionary *)info
// NSLog(@"Peer : %@ found.",peerID.displayName);
// if (![self.peerID isEqual:peerID])
NSLog(@"%@ Found Peer : %@",self.peerID.displayName,peerID.displayName);
[self.foundPeers addObject:peerID];
if (![self.connectedPeers containsObject:peerID])
if ([self.invitedPeers count] == 0 && [self.session.connectedPeers count]==0)
NSLog(@"%@ Invited Peer : %@",self.peerID.displayName,peerID.displayName);
[self.invitedPeers addObject:peerID];
[browser invitePeer:peerID
toSession:self.session
withContext:[@"Empath" dataUsingEncoding:NSUTF8StringEncoding]
timeout:0];
// [browser stopBrowsingForPeers];
self.invited = YES;
NSDictionary *userInfo = @ @"peerID": peerID ;
dispatch_async(dispatch_get_main_queue(), ^
[[NSNotificationCenter defaultCenter] postNotificationName:DidInviteNotification
object:nil
userInfo:userInfo];
);
//
// A nearby peer has stopped advertising
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID
[self.foundPeers removeObject:peerID];
[self.invitedPeers removeAllObjects];
[browser startBrowsingForPeers];
- (void)browser:(MCNearbyServiceBrowser *)browser didNotStartBrowsingForPeers:(NSError *)error
NSLog( @"Unable to start browsing for peers. Error: %@", error );
ViewController.m
#define DidChangeStateNotification @"E_DidChangeStateNotification"
#define DidReceiveDataNotification @"E_DidReceiveDataNotification"
#define DidInviteNotification @"E_DidInvitedNotification"
#define DidReceivedInvetationNotification @"E_DidReceivedInvetationNotification"
@interface ViewController ()
@property (nonatomic, strong) AppDelegate *appDelegate;
@end
@implementation ViewController
@synthesize txtMessage;
@synthesize tvHistory;
@synthesize btnSend;
@synthesize lblName;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
// self.appDelegate.connectedPeers = [NSMutableArray array];
// self.appDelegate.foundPeers = [NSMutableArray array];
[self AddObservers];
[self setUserInteraction:NO];
[self.lblName setText:@""];
[self.btnSend setUserInteractionEnabled:NO];
[self performSelector:@selector(advertisePeer) withObject:nil afterDelay:0.0];
-(void) AddObservers
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(handleReceivedDataWithNotification:)
name:DidReceiveDataNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(peerChangedStateWithNotification:)
name:DidChangeStateNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receivedInvetationWithNotification:)
name:DidReceivedInvetationNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(peerInvitedWithNotification:)
name:DidInviteNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(sessionDidTimeout:) name:kSessionDidTimeoutNotification object:nil];
-(void) advertisePeer
[self setUserInteraction:NO];
[self.lblName setText:@""];
[self.appDelegate.mpcHandler setupPeerWithDisplayName:[UIDevice currentDevice].name];
[self.appDelegate.mpcHandler setupSession];
[self.appDelegate.mpcHandler advertiseSelf:YES];
[self.btnSend setUserInteractionEnabled:YES];
- (IBAction)searchAndConnectPeer:(id)sender
[self.lblName setText:@"Searching..."];
if (self.appDelegate.mpcHandler.session != nil)
[[self.appDelegate mpcHandler] setupBrowser];
[[[self.appDelegate mpcHandler] browser] startBrowsingForPeers];
- (IBAction)sendMessage:(id)sender
NSString *messageToSend = [txtMessage text];
NSUInteger len = 0;
if ([messageToSend length])
NSData *messageAsData = [messageToSend dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
[self.appDelegate.mpcHandler.session sendData:messageAsData
toPeers:self.appDelegate.mpcHandler.session.connectedPeers
withMode:MCSessionSendDataReliable
error:&error];
// If any error occurs, just log it.
// Otherwise set the following couple of flags to YES, indicating that the current player is the creator
// of the game and a game is in progress.
len = [[tvHistory text] length];
if (error != nil)
NSLog(@"%@", [error localizedDescription]);
[self.tvHistory setText:[NSString stringWithFormat:@"%@",[error localizedDescription]]];
else
NSString *history = [NSString stringWithFormat:@"Me : %@\n\n",messageToSend];
[self.tvHistory setText:[self.tvHistory.text stringByAppendingString:history]];
[self.txtMessage setText:@""];
[self.tvHistory scrollRangeToVisible:NSMakeRange([self.tvHistory.text length], len)];
- (void)peerInvitedWithNotification:(NSNotification *)notification
[self setUserInteraction:NO];
MCPeerID *peerID = [[notification userInfo] objectForKey:@"peerID"];
[self.lblName setText:[NSString stringWithFormat:@"Connecting to %@...",peerID.displayName]];
- (void)receivedInvetationWithNotification:(NSNotification *)notification
[self setUserInteraction:YES];
NSString *name = [[notification userInfo] objectForKey:@"displayName"];
[self.lblName setText:[NSString stringWithFormat:@"Connected : %@",name]];
- (void)peerChangedStateWithNotification:(NSNotification *)notification
// Get the state of the peer.
int state = [[[notification userInfo] objectForKey:@"state"] intValue];
MCPeerID *peerID = [[notification userInfo] objectForKey:@"peerID"];
// We care only for the Connected and the Not Connected states.
// The Connecting state will be simply ignored.
if (state == MCSessionStateConnected)
// We'll just display all the connected peers (players) to the text view.
NSString *allPlayers = @"Connected : ";
allPlayers = [allPlayers stringByAppendingString:[NSString tringWithFormat:@"%@",peerID.displayName]];
[self.lblName setText:allPlayers];
[self setUserInteraction:YES];
NSLog(@"%@...",allPlayers);
// // Fire up the timer upon first event
// if(!_idleTimer)
// [self resetIdleTimer];
//
else if (state == MCSessionStateConnecting)
[self setUserInteraction:NO];
[self.lblName setText:[NSString stringWithFormat:@"Connecting to %@...",peerID.displayName]];
NSLog(@"Connecting %@...",peerID.displayName);
else if (state == MCSessionStateNotConnected)
NSLog(@"Disconnected %@...",peerID.displayName);
// [self sessionDidTimeout:nil];
-(void) setUserInteraction:(BOOL)enabled
[self.btnSend setUserInteractionEnabled:enabled];
[self.txtMessage setUserInteractionEnabled:enabled];
- (void)handleReceivedDataWithNotification:(NSNotification *)notification
// Get the user info dictionary that was received along with the notification.
NSDictionary *userInfoDict = [notification userInfo];
// Convert the received data into a NSString object.
NSData *receivedData = [userInfoDict objectForKey:@"data"];
NSString *message = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
// Keep the sender's peerID and get its display name.
MCPeerID *senderPeerID = [userInfoDict objectForKey:@"peerID"];
NSString *senderDisplayName = senderPeerID.displayName;
// Add this guess to the history text view.
NSUInteger len = [[tvHistory text] length];
NSString *history = [NSString stringWithFormat:@"%@ : %@\n\n", senderDisplayName, message];
[self.tvHistory setText:[self.tvHistory.text stringByAppendingString:history]];
[self.tvHistory scrollRangeToVisible:NSMakeRange([self.tvHistory.text length], len)];
-(BOOL)textFieldShouldReturn:(UITextField *)textField
[textField resignFirstResponder];
return YES;
- (void)resetIdleTimer
if (_idleTimer)
[_idleTimer invalidate];
// Schedule a timer to fire in kApplicationTimeoutInMinutes * 60
int timeout = kSessionTimeoutInSeconds;
_idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout
target:self
selector:@selector(idleTimerExceeded)
userInfo:nil
repeats:NO];
- (void)idleTimerExceeded
/* Post a notification so anyone who subscribes to it can be notified when
* the application times out */
[[NSNotificationCenter defaultCenter]
postNotificationName:kSessionDidTimeoutNotification object:nil];
- (void) sessionDidTimeout:(NSNotification *) notif
// [self setUserInteraction:NO];
//
// [self.lblName setText:@"Session expired..."];
//
// NSLog(@"============================Session Expired...=====================");
//
// [[[self.appDelegate mpcHandler] session] disconnect];
//
// if ([[[self appDelegate]mpcHandler] invited])
// [self performSelector:@selector(advertisePeer) withObject:nil afterDelay:0.0];
// [self performSelector:@selector(searchAndConnectPeer:) withObject:nil afterDelay:1.0];
//
【问题讨论】:
任何人都可以在上面指导我 您同时浏览和投放广告。看看这个 SO 问题:***.com/questions/19469984/… 【参考方案1】:检查 BTM 断开 以在日志中提供服务消息。他们已确认 Apple 蓝牙存在问题。尝试不使用蓝牙,即点对点 wifi 或基础设施网络
【讨论】:
以上是关于蓝牙连接立即断开多点框架的主要内容,如果未能解决你的问题,请参考以下文章