8

I would like to setup a client-server architecture for streaming data between multiple iPhones. For instance, the 'server' iPhone hosts a master list of animals. An arbitrary number of client iPhones can connect to the server iPhone then read and edit the list. Some methods I have tried:

  • Multipeer connectivity - Only supports up to 8 clients. Would be exactly what Im looking for if there were a way around this
  • GameKit - Ive read that bluetooth connection can be buggy when dealing with multiple clients
  • BLE - characteristic values for bluetooth are limited to 512 octets. I assume the list of animals, when archived, may grow to be larger than the maximum characteristic value.
  • sockets - I'd rather not have to rely on an outside server

I'm willing to entertain 'hacky' solutions. I was thinking of broadcasting each animal as a separate characteristic, but this may slow down discovery and I have a feeling it will cause a few other headaches. Any help would be greatly appreciated

Ethan Blackburn
  • 497
  • 5
  • 13

1 Answers1

14

Multipeer Connectivity does only support 8 peers per session, but it supports multiple sessions. In your case, where there is a single 'server' device with many clients, and the clients don't need to see each other, the 'server' can just create new sessions as needed.

So with the 'server' peer acting as advertiser, and accepting invitations, have a method that returns an existing session or creates a new one:

- (MCSession *)availableSession {

   //Try and use an existing session (_sessions is a mutable array)
   for (MCSession *session in _sessions)
       if ([session.connectedPeers count]<kMCSessionMaximumNumberOfPeers)
           return session;

    //Or create a new session
    MCSession *newSession = [self newSession];
    [_sessions addObject:newSession];

    return newSession;
}

- (MCSession *)newSession {

    MCSession *session = [[MCSession alloc] initWithPeer:_myPeerID securityIdentity:nil encryptionPreference:MCEncryptionNone];
    session.delegate = self;

    return session;
}

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void (^)(BOOL, MCSession *))invitationHandler {

    MCSession *session = [self availableSession];
    invitationHandler(YES,session);
}

I then have this method for sending:

- (void)sendData:(NSData *)data toPeers:(NSArray *)peerIDs reliable:(BOOL)reliable error:(NSError *__autoreleasing *)error {

    if ([peerIDs count]==0)
        return;

    NSPredicate *peerNamePred = [NSPredicate predicateWithFormat:@"displayName in %@", [peerIDs valueForKey:@"displayName"]];

    MCSessionSendDataMode mode = (reliable) ? MCSessionSendDataReliable : MCSessionSendDataUnreliable;

    //Need to match up peers to their session
    for (MCSession *session in _sessions){

        NSError __autoreleasing *currentError = nil;

        NSArray *filteredPeerIDs = [session.connectedPeers filteredArrayUsingPredicate:peerNamePred];

        [session sendData:data toPeers:filteredPeerIDs withMode:mode error:&currentError];

        if (currentError && !error)
            *error = currentError;
    }
}

There are certainly performance optimizations that can be made to this approach, but for the frequency with which I am sending data to peers this has worked well enough.

ChrisH
  • 4,468
  • 2
  • 33
  • 42
  • Brilliant. Do you have any information on keeping multi peer connectivity bluetooth active in background mode? – Ethan Blackburn Jan 03 '14 at 23:53
  • You won't be able to discover peers in the background but I have been able to transfer data between already-connected peers. I answered a similiar question here: http://stackoverflow.com/questions/20480600/does-startadvertisingpeer-work-when-app-enters-background/20508679#20508679 – ChrisH Jan 04 '14 at 15:30
  • @ChrisH can you recommend a solution where all 45 devices could see each other and chat? This solution looks like only the server would be able to see all the devices, and the devices would probably have to be in close range. I'm looking for something where hundreds of users could be spread out and chained together, able to chat. – codeman Apr 15 '14 at 15:05