P 2 P速伝ノート

12849 ワード

P 2 P対面速伝のクライアント


特に注意してください.ここではデバッグ中に点を折らないでください.点を折るとすぐに断線します.覚えておいてください.

ヘッダファイル

@protocol PeerAmongClientManagerDelegate 

@required
- (void)reviceDataFromServer:(NSData *)data;

@optional
- (void)connected;
- (void)losted;
- (BOOL)acceptWithDisplayName:(NSString *)displayName;
@end

@interface PeerAmongClientManager : NSObject
@property (assign, nonatomic) NSObject *delegate;
- (instancetype)initWithDisplayName:(NSString *)displayName;
- (void)connectServer;
- (void)cancelConnect;
- (BOOL)sendMessageToServerWithData:(NSData *)data;
@end

ファイルの実行

#import "PeerAmongClientManager.h"
#import 

#define MAIN_QUEUE_TODO(code) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\
code;\
})

#define ServiceType @"peerservice"

@interface PeerAmongClientManager () 
@property (strong, nonatomic) MCPeerID *localPeerID;
@property (strong, nonatomic) MCNearbyServiceAdvertiser *nearbyServiceAdvertiser;

@property (copy, nonatomic) void (^invitationHandler)(BOOL accept, MCSession *session);
@property (strong, nonatomic) MCSession *connectedSession;
@property (copy, nonatomic) NSString *displayName;
@end

@implementation PeerAmongClientManager

- (instancetype)initWithDisplayName:(NSString *)displayName {
    if(self = [super init]) {
        self.displayName = displayName;
    }
    return self;
}

- (MCPeerID *)localPeerID {
    if(_localPeerID == nil) {
        _localPeerID = [[MCPeerID alloc] initWithDisplayName:self.displayName?:@"Client"];
        
    }
    return _localPeerID;
}

- (MCSession *)connectedSession {
    if(_connectedSession == nil) {
        _connectedSession = [[MCSession alloc] initWithPeer:self.localPeerID];
        _connectedSession.delegate = self;
    }
    return _connectedSession;
}

- (MCNearbyServiceAdvertiser *)nearbyServiceAdvertiser {
    if(_nearbyServiceAdvertiser == nil) {
        _nearbyServiceAdvertiser = [[MCNearbyServiceAdvertiser alloc] initWithPeer:self.localPeerID discoveryInfo:nil serviceType:ServiceType];
        
        _nearbyServiceAdvertiser.delegate = self;
    }
    return _nearbyServiceAdvertiser;
}

- (void)connectServer {
    [self.nearbyServiceAdvertiser startAdvertisingPeer];
}

- (void)cancelConnect {
    [self.nearbyServiceAdvertiser stopAdvertisingPeer];
}

- (BOOL)sendMessageToServerWithData:(NSData *)data {
    BOOL sendStatus = NO;
    if(!data || !self.connectedSession) {
        return sendStatus;
    }
    sendStatus = [self.connectedSession sendData:data toPeers:self.connectedSession.connectedPeers withMode:MCSessionSendDataReliable error:nil];
    return sendStatus;
}

#pragma mark MCNearbyServiceAdvertiserDelegate

- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser
  didReceiveInvitationFromPeer:(MCPeerID *)peerID
                   withContext:(nullable NSData *)context
             invitationHandler:(void (^)(BOOL accept, MCSession *session))invitationHandler {
    self.invitationHandler = invitationHandler;
    if([self.delegate respondsToSelector:@selector(acceptWithDisplayName:)]) {
        self.invitationHandler([self.delegate acceptWithDisplayName:peerID.displayName],self.connectedSession);
    }
    else {
        self.invitationHandler(YES,self.connectedSession);
    }
}


#pragma mark MCSessionDelegate 

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state {
    self.connectedSession = session;
    if(state == MCSessionStateConnected) {
        self.connectedSession.delegate = self;
        if([self.delegate respondsToSelector:@selector(connected)]) {
            MAIN_QUEUE_TODO([self.delegate connected]);
        }
    }
    else if (state == MCSessionStateNotConnected) {
        self.connectedSession = nil;
        if([self.delegate respondsToSelector:@selector(losted)]) {
            MAIN_QUEUE_TODO([self.delegate losted]);
        }
    }
}

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {
    if([self.delegate respondsToSelector:@selector(reviceDataFromServer:)]) {
        [self.delegate performSelectorOnMainThread:@selector(reviceDataFromServer:) withObject:data waitUntilDone:NO];
    }
}


- (void)session:(MCSession *)session
didReceiveStream:(NSInputStream *)stream
       withName:(NSString *)streamName
       fromPeer:(MCPeerID *)peerID {
    //to do sth...
}

// Start receiving a resource from remote peer.
- (void)session:(MCSession *)session
didStartReceivingResourceWithName:(NSString *)resourceName
       fromPeer:(MCPeerID *)peerID
   withProgress:(NSProgress *)progress {
    //to do sth...
}

- (void)session:(MCSession *)session
didFinishReceivingResourceWithName:(NSString *)resourceName
       fromPeer:(MCPeerID *)peerID
          atURL:(NSURL *)localURL
      withError:(nullable NSError *)error {
    //to do sth...
}


@end

面と向かって速く伝えるサービス端


ヘッダファイル

@protocol PeerAmongServerManagerDelegate 

@required
- (void)reviceMessageFromClient:(NSData *)data;

@optional
- (void)connectedWithDisplayName:(NSString *)displayName;
- (void)lostWithDisplayName:(NSString *)displayName;

@end

@interface PeerAmongServerManager : NSObject
@property (assign, nonatomic) NSObject *delegate;
@property (copy, nonatomic, readonly) NSArray *connectedPeerIds;
- (instancetype)initWithDisplayName:(NSString *)displayName;
- (void)scanClient;
- (void)cancelScan;
- (BOOL)sendMessageToAllWithData:(NSData *)data;
- (BOOL)sendMessageToDisplayName:(NSString *)displayName data:(NSData *)data;
//  
- (void)addBlockWithDisplayName:(NSString *)displayName;
//  
- (void)removeBlockWithDisplayName:(NSString *)displayName;
@end

ファイルの実行

#import "PeerAmongServerManager.h"
#import 

#define MAIN_QUEUE_TODO(code) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\
code;\
})

#define ServiceType @"peerservice"

@interface PeerAmongServerManager () 
@property (strong, nonatomic) MCPeerID *localPeerID;
@property (strong, nonatomic) MCNearbyServiceBrowser *nearbyServiceBrowser;
@property (strong, nonatomic) MCSession *connectedSession;
@property (strong, nonatomic) NSMutableDictionary *connectedSessionDictionary;
@property (copy, nonatomic) NSString *displayName;
@property (strong, nonatomic) NSMutableArray *blockDisplayNameArray;
@end

@implementation PeerAmongServerManager


- (instancetype)initWithDisplayName:(NSString *)displayName {
    if(self = [super init]) {
        self.displayName = displayName;
    }
    return self;
}

- (NSArray *)connectedPeerIds {
    return [self.connectedSession.connectedPeers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"not (self.displayName in (%@))",self.blockDisplayNameArray]];
}

- (NSMutableArray *)blockDisplayNameArray {
    if(_blockDisplayNameArray == nil) {
        _blockDisplayNameArray = [NSMutableArray array];
    }
    return _blockDisplayNameArray;
}

- (MCPeerID *)localPeerID {
    if(_localPeerID == nil) {
        _localPeerID = [[MCPeerID alloc] initWithDisplayName:self.displayName?:@"Server"];
    }
    return _localPeerID;
}

- (NSMutableDictionary *)connectedSessionDictionary {
    if(_connectedSessionDictionary == nil) {
        _connectedSessionDictionary = [NSMutableDictionary dictionary];
    }
    return _connectedSessionDictionary;
}

- (MCSession *)connectedSession {
    if(_connectedSession == nil) {
        _connectedSession = [[MCSession alloc] initWithPeer:self.localPeerID];
        _connectedSession.delegate = self;
    }
    return _connectedSession;
}

- (MCNearbyServiceBrowser *)nearbyServiceBrowser {
    if(_nearbyServiceBrowser == nil) {
        _nearbyServiceBrowser = [[MCNearbyServiceBrowser alloc] initWithPeer:self.localPeerID serviceType:ServiceType];
        _nearbyServiceBrowser.delegate = self;
    }
    return _nearbyServiceBrowser;
}

- (void)scanClient {
    [self.nearbyServiceBrowser startBrowsingForPeers];
}

- (void)cancelScan {
    [self.nearbyServiceBrowser stopBrowsingForPeers];
}

- (void)addBlockWithDisplayName:(NSString *)displayName {
    if(displayName) {
        [self.blockDisplayNameArray addObject:displayName];
    }
}

- (void)removeBlockWithDisplayName:(NSString *)displayName {
    [self.blockDisplayNameArray removeObject:displayName];
}

- (BOOL)sendMessageToAllWithData:(NSData *)data {
    BOOL sendStatus = NO;
    if(!data) {
        return sendStatus;
    }
    NSError *error = nil;
    
    if(self.connectedPeerIds.count > 0) {
        sendStatus = [self.connectedSession sendData:data toPeers:self.connectedPeerIds withMode:MCSessionSendDataReliable error:&error];
    }
    NSLog(@"error:%@",error);
    return sendStatus;
}

- (BOOL)sendMessageToDisplayName:(NSString *)displayName data:(NSData *)data {
    BOOL sendStatus = NO;
    if(!displayName || !data) {
        return sendStatus;
    }
    
    NSArray *peerIdsArray = [self.connectedSession.connectedPeers filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self.displayName == %@",displayName]];
    if(peerIdsArray.count == 0) {
        return sendStatus;
    }
    NSError *error = nil;
    sendStatus = [self.connectedSession sendData:data toPeers:peerIdsArray withMode:MCSessionSendDataReliable error:&error];
    return sendStatus;
    
    
}

#pragma mark MCNearbyServiceBrowserDelegate

- (void)browser:(MCNearbyServiceBrowser *)browser
              foundPeer:(MCPeerID *)peerID
      withDiscoveryInfo:(nullable NSDictionary *)info {
    [self.nearbyServiceBrowser invitePeer:peerID toSession:self.connectedSession withContext:nil timeout:100];
}

// A nearby peer has stopped advertising.
- (void)browser:(MCNearbyServiceBrowser *)browser lostPeer:(MCPeerID *)peerID {
    if([self.delegate respondsToSelector:@selector(lostWithDisplayName:)]) {
        [self.delegate performSelectorOnMainThread:@selector(lostWithDisplayName:) withObject:peerID.displayName waitUntilDone:NO];
    }
    NSLog(@"lost:%@",peerID.displayName);
}

#pragma mark MCSessionDelegate

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state {
    if(state == MCSessionStateConnecting) {
        [self.connectedSessionDictionary setObject:session forKey:peerID.displayName];
    }
    else if(state == MCSessionStateNotConnected) {
        
        [self.connectedSessionDictionary removeObjectForKey:peerID.displayName];
        if([self.delegate respondsToSelector:@selector(lostWithDisplayName:)]) {
            [self.delegate performSelectorOnMainThread:@selector(lostWithDisplayName:) withObject:peerID.displayName waitUntilDone:NO];
        }
    }
    else if(state == MCSessionStateConnected) {
        NSLog(@"peers:%@",self.connectedSession.connectedPeers);
        session.delegate = self;
        [self.connectedSessionDictionary setObject:session forKey:peerID.displayName];
        if([self.delegate respondsToSelector:@selector(connectedWithDisplayName:)]) {
            [self.delegate performSelectorOnMainThread:@selector(connectedWithDisplayName:) withObject:peerID.displayName waitUntilDone:NO];
        }
    }
}

- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID {
    if([self.delegate respondsToSelector:@selector(reviceMessageFromClient:)]) {
        [self.delegate performSelectorOnMainThread:@selector(reviceMessageFromClient:) withObject:data waitUntilDone:NO];
    }
}

- (void)session:(MCSession *)session
   didReceiveStream:(NSInputStream *)stream
           withName:(NSString *)streamName
           fromPeer:(MCPeerID *)peerID {
//    to to sth...
}

// Start receiving a resource from remote peer.
- (void)session:(MCSession *)session
  didStartReceivingResourceWithName:(NSString *)resourceName
                           fromPeer:(MCPeerID *)peerID
                       withProgress:(NSProgress *)progress {
//    to to sth...
}

- (void)session:(MCSession *)session
 didFinishReceivingResourceWithName:(NSString *)resourceName
                           fromPeer:(MCPeerID *)peerID
                              atURL:(NSURL *)localURL
                          withError:(nullable NSError *)error {
//    to to sth...
}

@end