Best option for streaming data between iPhones

折月煮酒 提交于 2019-11-28 21:40:59

问题


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


回答1:


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.



来源:https://stackoverflow.com/questions/20896791/best-option-for-streaming-data-between-iphones

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!