P2P面对面快传之客户端
特别提醒,这里在调试的时候千万不要打断点,一打断点就马上断线,请牢记。
头文件
@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
执行文件
#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
面对面快传之服务端
头文件
@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
执行文件
#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