Tuesday 15 January 2013

ios - Multipeer Connectivity data only sends one way even when both devices are connected -



ios - Multipeer Connectivity data only sends one way even when both devices are connected -

i have 2 devices connected each other on multi-peer connectivity framework. when connected each device instantly send packet of nsdata each other, in first instance info contain sound , image. appears work fine , both user receive relevant data.

the users can select each other view , send bit of data. i'm seeing if host (the client sent invitation) attempts send more info next error displayed in console.

peers ( peername ) not connected

but if client (the invitee) sends info arrives expected on host. interesting fact have nslogs in the:

-(void)peerdidchangestatewithnotification:(nsnotification *)notification

method fire when disconnect occurs, there no disconnects occurring , devices connected 1 another. code below, have thought why might occur?

#pragma mark send buzz notification #pragma mark - -(void)sendbuzznotification{ // create user (remove image lower size) localuserclass *withoutimage = [[localuserclass alloc]initwithname:[[[globaldata sharedglobaldata]localuser]personname] personimage:nil personsound:[[[globaldata sharedglobaldata]localuser]personsound] personpeerid:nil]; // send users sound , name other peer/s nsdata *datatosend = [nskeyedarchiver archiveddatawithrootobject:withoutimage]; nserror *error; // skip if no users selcted if ([selectedusers count] == 0) { return; } else{ // create array of peer ids selected users nsmutablearray *temparray = [[nsmutablearray alloc]init]; (localuserclass *object in selectedusers) { // add together peer id mcpeerid *theid = object.personpeerid; [temparray addobject:theid]; } nsarray *theusers = [[nsarray alloc]init]; theusers = temparray; // send info [appdelegate.mcmanager.session senddata:datatosend topeers:theusers withmode:mcsessionsenddatareliable error:&error]; if (error) { nslog(@"%@", [error localizeddescription]); } // vibrate device show been sent audioservicesplaysystemsound(ksystemsoundid_vibrate); } } #pragma mark peer connected state checker #pragma mark - -(void)peerdidchangestatewithnotification:(nsnotification *)notification{ mcpeerid *peerid = [[notification userinfo] objectforkey:@"peerid"]; //nslog(@"%@",peerid.displayname); mcsessionstate state = [[[notification userinfo] objectforkey:@"state"] intvalue]; localuserclass *theuser = [[localuserclass alloc]initwithname:peerid.displayname personimage:nil personsound:nil personpeerid:peerid]; //nslog(@"the user name is: %@ user sound is: %@ user peer id %@",theuser.personname,theuser.personsound,theuser.personpeerid); if (state != mcsessionstateconnecting) { if (state == mcsessionstateconnected) { // add together user [connectedusers addobject:theuser]; // send users details newly connected peer (profile pic , sound) [self senduserdetailstopeer:peerid]; } else if (state == mcsessionstatenotconnected){ // have connections if ([connectedusers count] > 0) { // user remove nsinteger thepeerindex = 0; nsinteger thepeerindexselectedusers = 0; (localuserclass *object in connectedusers) { if (object.personpeerid == theuser.personpeerid) { thepeerindex = [connectedusers indexofobject:object]; [connectedusers removeobjectatindex:thepeerindex]; } } (localuserclass *user in selectedusers) { if (user.personpeerid == theuser.personpeerid) { thepeerindexselectedusers = [selectedusers indexofobject:user]; [selectedusers removeobjectatindex:thepeerindexselectedusers]; } } } } } // force main queue speedy response dispatch_async(dispatch_get_main_queue(), ^(void) { // create user playback devices [playbackmanager createuseraudioplayers:connectedusers withsound:nil]; [collview reloaddata]; [self populateuserbox]; bool peersexist = ([[appdelegate.mcmanager.session connectedpeers] count] == 0); //nslog(@"peer count %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]]; } }); } #pragma mark peer received info #pragma mark - -(void)didreceivedatawithnotification:(nsnotification *)notification{ nsdata *receiveddata = [[notification userinfo] objectforkey:@"data"]; receiveduser = [nskeyedunarchiver unarchiveobjectwithdata:receiveddata]; cgimageref cgref = [receiveduser.personimage cgimage]; ciimage *cim = [receiveduser.personimage ciimage]; // getting whole user or user sound , name (check no image) if (cim == nil && cgref == null) { // recieve info (todo needs run in background) [self performselectoronmainthread:@selector(recievebuzznotification) withobject:nil waituntildone:yes]; } else{ // recieve info (todo needs run in background) [self performselectoronmainthread:@selector(receiveduserprofile) withobject:nil waituntildone:yes]; } }

update: host appears lose connection client after inital info transfer:

[self senduserdetailstopeer:peerid];

however disconnection state doesn't fire anything, , client can still send info host. seen logging out connected sessions:

session.connectedpeers

edit: additional code view controller:

#pragma mark create session #pragma mark - -(void)setupsession{ // create session , peer details user [appdelegate.mcmanager setuppeerandsessionwithdisplayname:[[[globaldata sharedglobaldata]localuser]personname]]; [appdelegate.mcmanager advertiseself:visibleswitch.ison]; appdelegate.mcmanager.browser.delegate = self; // set global user peerid [[[globaldata sharedglobaldata]localuser]setpersonpeerid:appdelegate.mcmanager.peeridglobal]; // setup notification track user info of connected peers [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(peerdidchangestatewithnotification:) name:@"mcdidchangestatenotification" object:nil]; // notifcation track recieved info [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(didreceivedatawithnotification:) name:@"mcdidreceivedatanotification" object:nil]; }

and mcmanager:

-(id)init{ self = [super init]; if (self) { peeridglobal = nil; session = nil; browser = nil; advertiser = nil; } homecoming self; } //----custom---------------------------------------------------------------------------------------------------------------// //-------------------------------------------------------------------------------------------------------------------------// //----public---------------------------------------------------------------------------------------------------------------// #pragma mark setup peer , session #pragma mark - -(void)setuppeerandsessionwithdisplayname:(nsstring *)displayname{ peeridglobal = [[mcpeerid alloc] initwithdisplayname:[[[globaldata sharedglobaldata]localuser]personname]]; session = [[mcsession alloc] initwithpeer:peeridglobal]; session.delegate = self; } #pragma mark setup browser #pragma mark - -(void)setupmcbrowser{ browser = [[mcbrowserviewcontroller alloc] initwithservicetype:@"chat-files" session:session]; } #pragma mark setup advertiser #pragma mark - -(void)advertiseself:(bool)shouldadvertise{ if (shouldadvertise) { advertiser = [[mcadvertiserassistant alloc] initwithservicetype:@"chat-files" discoveryinfo:nil session:session]; [advertiser start]; } else{ [advertiser stop]; advertiser = nil; } } //----delegates------------------------------------------------------------------------------------------------------------// //-------------------------------------------------------------------------------------------------------------------------// #pragma mark session delegate #pragma mark - -(void)session:(mcsession *)session peer:(mcpeerid *)peerid didchangestate:(mcsessionstate)state{ // create dict connected user info nsdictionary *dict = @{@"peerid": peerid, @"state" : [nsnumber numberwithint:state] }; // post notification tracking [[nsnotificationcenter defaultcenter] postnotificationname:@"mcdidchangestatenotification" object:nil userinfo:dict]; } -(void)session:(mcsession *)session didreceivedata:(nsdata *)data frompeer:(mcpeerid *)peerid{ nsdictionary *dict = @{@"data": data, @"peerid": peerid }; [[nsnotificationcenter defaultcenter] postnotificationname:@"mcdidreceivedatanotification" object:nil userinfo:dict]; }

thanks chris, looks issue, i've rewritten code based on boilerplate code here: https://github.com/shrtlist/mcsessionp2p

now app automatically connects users without browsers, it's great solution , highly recommend problems have @ code.

ios objective-c multipeer-connectivity

No comments:

Post a Comment