P2P快傳筆記

P2P面對面快傳之客戶端

特別提醒,這里在調(diào)試的時候千萬不要打斷點,一打斷點就馬上斷線,請牢記。

頭文件

@protocol PeerAmongClientManagerDelegate <NSObject>

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

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

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

執(zhí)行文件

#import "PeerAmongClientManager.h"
#import <MultipeerConnectivity/MultipeerConnectivity.h>

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

#define ServiceType @"peerservice"

@interface PeerAmongClientManager () <MCNearbyServiceAdvertiserDelegate, MCSessionDelegate>
@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

面對面快傳之服務(wù)端

頭文件

@protocol PeerAmongServerManagerDelegate <NSObject>

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

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

@end

@interface PeerAmongServerManager : NSObject
@property (assign, nonatomic) NSObject<PeerAmongServerManagerDelegate> *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

執(zhí)行文件

#import "PeerAmongServerManager.h"
#import <MultipeerConnectivity/MultipeerConnectivity.h>

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

#define ServiceType @"peerservice"

@interface PeerAmongServerManager () <MCNearbyServiceBrowserDelegate, MCSessionDelegate>
@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<NSString *, NSString *> *)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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容