根据文档,MCSessionStateNotConnected 可以表示
"...附近的对等体拒绝了邀请,连接无法
已建立,或者以前连接的对等方不再连接。”
您没有在问题中说什么会导致邀请被拒绝,但假设它是用户驱动的,一种方法可能是让您的 MCNearbyServiceAdvertiserDelegate 自动接受邀请,为每个同行创建一个新会话,然后向用户展示接受或拒绝连接的选择。在收到表明用户决定的后续消息之前,您的同行不会被视为真正处于会话中:
所以在你的 MCNearbyServiceAdvertiserDelegate 类中你会接受然后提示用户:
- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser
didReceiveInvitationFromPeer:(MCPeerID *)peerID
withContext:(NSData *)context
invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler {
//Automatically accept with a new session
MCSession *newSession = [[MCSession alloc] initWithPeer:_myPeerID];
newSession.delegate = self;
//Keep track of the pending sessions in a mutable dictionary
_pendingSessionPeerIDMap[peerID.displayName] = newSession;
invitationHandler(YES,newSession);
/* Code here to present user with option to accept or decline peer */
}
然后当用户响应时,你可以有一个方法发送一个简单的字符串作为包含状态的 NSData:
@property NSData *inviteAcceptedMsgData = [@"MPCInviteYES" dataUsingEncoding:NSUTF8StringEncoding];
@property NSData *inviteDeclinedMsgData = [@"MPCInviteNO" dataUsingEncoding:NSUTF8StringEncoding];
- (void)invitationFromPeerID:(MCPeerID *)peerID receivedResponse:(BOOL)accepted {
//Send a message to the peer that sent the invitation indicating whether the
//user accepted or declined
NSData *msgData = (accepted) ? _inviteAcceptedMsgData : _inviteDeclinedMsgData;
MCSession *peerSession = _pendingSessionPeerIDMap[peerID.displayName];
[peerSession sendData:msgData
toPeers:@[peerID]
withMode:MCSessionSendDataReliable
error:nil];
//Remove the pending session
[_pendingSessionPeerIDMap removeObjectForKey:peerID.displayName];
//And if the connection was accepted by the user, add to an accepted dictionary
_acceptedSessionPeerIDMap[peerID.displayName] = peerSession;
}
MCNearbyServiceBrowserDelegate 的工作方式类似:
- (void)browser:(MCNearbyServiceBrowser *)browser
foundPeer:(MCPeerID *)peerID
withDiscoveryInfo:(NSDictionary *)info {
//Send the invitation with a new session
MCSession *newSession = [[MCSession alloc] initWithPeer:_myPeerID];
newSession.delegate = self;
[browser invitePeer:peerID
toSession:newSession
withContext:nil
timeOut:0];
}
然后浏览器将等待来自它所邀请的对等方的消息以确定邀请是否被真正接受:
- (void)session:(MCSession *)session
didReceiveData:(NSData *)data
fromPeer:(MCPeerID *)peerID {
//Check the data to see whether invite was accepted
if ([data isEqualToData:_inviteAcceptedMsgData]) {
//Add to an accepted dictionary
_acceptedSessionPeerIDMap[peerID.displayName] = session;
}
else if ([data isEqualToData:_inviteAcceptedMsgData]){
//Disconnect the session
[session disconnect];
}
}
您可能已经有一个消息系统,但这代表了在连接的对等点之间传递状态的简单实现。就发送广播或显示连接的对等点而言,_acceptedSessionPeerIDMap 应作为对等点的真正集合。