ipv6的多人连接问题没有收到邀请

Posted

技术标签:

【中文标题】ipv6的多人连接问题没有收到邀请【英文标题】:Multipeer Connection issue with ipv6 don't get an invitation 【发布时间】:2016-12-12 09:16:15 【问题描述】:

我的应用程序被 Apple 拒绝,因为它无法通过连接到 IPv6 网络的 Wi-Fi 连接到运行 ios 10.1.1 的其他设备。 当我点击连接时,应用程序会继续搜索受邀者,并且不会产生进一步的用户操作。 我使用多点连接,我从未测试过我的应用程序连接到 IPv6(这是我的第一个版本)。但该应用程序运行良好,无需任何连接或连接到 IPv4 网络。

我不知道为什么应用程序使用 IPv4 运行并连接良好,并且如果 iPad 连接到 IPv6 网络,则无法连接到对等体。

所以我的问题:是否可以通过 IPv6 使用多点连接,以便 Apple 可以批准该应用程序,或者我应该如何处理这个问题?

这是我的代码,可能有问题。

@interface ConnectionManageriOS7 () <MCSessionDelegate, MCBrowserViewControllerDelegate>
 
    UILocalNotification *_expireNotification;
    UIBackgroundTaskIdentifier _taskId;


@property (nonatomic, strong) MCSession *session;
@property (nonatomic, strong) MCPeerID *localPeerID;

@property (nonatomic, strong) MCBrowserViewController *browserVC;
@property (nonatomic, strong) MCAdvertiserAssistant *advertiser;

@end

static ConnectionManageriOS7 *_manager = nil;

@implementation ConnectionManageriOS7

+ (ConnectionManageriOS7 *)connectManager 

    @synchronized([ConnectionManageriOS7 class])

        if (_manager == nil) 
            _manager = [[ConnectionManageriOS7 alloc] init];
        
        return _manager;
    
    return nil;


- (id)init 

    self = [super init];
    if (self) 
        [self setupSessionAndAdvertiser];
    
    return self;


- (void)setupSessionAndAdvertiser 

    _localPeerID = [[MCPeerID alloc] initWithDisplayName:[UIDevice currentDevice].name];;
    _session = [[MCSession alloc] initWithPeer:_localPeerID];
    _session.delegate = self;



- (void)connectWithDelegate:(id)delegate 

    _delegate = delegate;
    if (_session.connectedPeers.count) 
        if ([_delegate respondsToSelector:@selector(didConntectedWithManager:)]) 
            [_delegate didConntectedWithManager:self];
        
     else 
        if (_advertiser == nil) 
            _advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:VISUS_Service
                                                               discoveryInfo:nil
                                                                     session:_session];

            _isConnected = NO;

            [_advertiser start];
        
        if (_browserVC == nil) 

            _browserVC = [[MCBrowserViewController alloc] initWithServiceType:VISUS_Service session:_session];
            _browserVC.delegate = self;

        

        [(UIViewController *)delegate presentViewController:_browserVC
                                                   animated:YES completion:nil];
    


- (void)sendMessage:(NSString *)message 

    NSData *textData = [message dataUsingEncoding:NSASCIIStringEncoding];
    NSLog(@"Send Data: %@", message);
    NSError *error = nil;
    [_session sendData:textData
               toPeers:_session.connectedPeers
              withMode:MCSessionSendDataReliable
                 error:&error];

    if (error) 
        //        
        [self session:_session peer:nil didChangeState:MCSessionStateNotConnected];
        NSLog(@"error %@", error.userInfo);
    


- (void)stopService 

    NSLog(@"Stop Service");

    [_advertiser stop];
    _advertiser = nil;

    _browserVC = nil;


#pragma marks -
#pragma marks MCBrowserViewControllerDelegate
- (void) dismissBrowserVC
    [_browserVC dismissViewControllerAnimated:YES completion:nil];

// Notifies the delegate, when the user taps the done button
- (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController 

    if ([_delegate respondsToSelector:@selector(didConntectedWithManager:)]) 
        [_delegate didConntectedWithManager:self];
    

    [self dismissBrowserVC];


// Notifies delegate that the user taps the cancel button.
- (void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController
    if (_browserVC == nil) 
        [browserViewController dismissViewControllerAnimated:YES completion:nil];
    else 
        [self dismissBrowserVC];
    


#pragma marks -
#pragma marks MCBrowserViewControllerDelegate

- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state 

    if (state != MCSessionStateConnecting) 
        if (state == MCSessionStateConnected) 

            _isConnected = true;
            if ([_delegate respondsToSelector:@selector(willConntectedWithManager:)]) 
                [_delegate willConntectedWithManager:self];
            
        
        else 

            _isConnected = false;
            [self stopService];
            if ([_delegate respondsToSelector:@selector(didDisconntectedWithManager:)]) 
                [_delegate didDisconntectedWithManager:self];
            
        

    



// Received data from remote peer
- (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID
    //  Decode data back to NSString

    NSString *message = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"Receive Data: %@", message);

    //  append message to text box:
    dispatch_async(dispatch_get_main_queue(), ^
        if ([_delegate respondsToSelector:@selector(connectionManager:receivedString:)]) 
            [_delegate connectionManager:self receivedString:message];
        
    );


- (void)session:(MCSession *)session didFinishReceivingResourceWithName:(NSString *)resourceName fromPeer:(MCPeerID *)peerID atURL:(NSURL *)localURL withError:(NSError *)error 

    _isConnected = false;
    [self stopService];
    NSLog(@"----- Error ----- %@", error.localizedDescription);



// Received a byte stream from remote peer
- (void)session:(MCSession *)session didReceiveStream:(NSInputStream *)stream withName:(NSString *)streamName fromPeer:(MCPeerID *)peerID 



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



- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler

    certificateHandler(YES);



- (void) createExpireNotification

    [self killExpireNotification];

    if (_session.connectedPeers.count != 0) // if peers connected, setup kill switch
    
        NSTimeInterval gracePeriod = 20.0f;

        // create notification that will get the user back into the app when the background process time is about to expire
        NSTimeInterval msgTime = UIApplication.sharedApplication.backgroundTimeRemaining - gracePeriod;
        UILocalNotification* n = [[UILocalNotification alloc] init];
        _expireNotification = n;
        _expireNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:msgTime];
        _expireNotification.alertBody = @"Bluetooth Connectivity is about to disconnect. Open the app to resume Test";
        _expireNotification.soundName = UILocalNotificationDefaultSoundName;
        _expireNotification.applicationIconBadgeNumber = 1;

        [UIApplication.sharedApplication scheduleLocalNotification:_expireNotification];
    


- (void) killExpireNotification

    if (_expireNotification != nil)
    
        [UIApplication.sharedApplication cancelLocalNotification:_expireNotification];
        _expireNotification = nil;
    


- (void)bacgroundHandling 

    _taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
               
                   [self stopService];
                   [[UIApplication sharedApplication] endBackgroundTask:_taskId];
                   _taskId = UIBackgroundTaskInvalid;
               ];
    [self createExpireNotification];



- (void)advertiser:(MCNearbyServiceAdvertiser *)advertiser didReceiveInvitationFromPeer:(MCPeerID *)peerID withContext:(NSData *)context invitationHandler:(void(^)(BOOL accept, MCSession *session))invitationHandler


    // http://down.vcnc.co.kr/WWDC_2013/Video/708.pdf  -- wwdc tutorial, this part is towards the end (p119)

   // self.arrayInvitationHandler = [NSArray arrayWithObject:[invitationHandler copy]];
    // ask the user
    UIAlertView *alertView = [[UIAlertView alloc]
                              initWithTitle:peerID.displayName
                              message:@"Would like to create a session with you"
                              delegate:self
                              cancelButtonTitle:@"Decline" otherButtonTitles:@"Accept", nil];
    [alertView show];




- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

    // retrieve the invitationHandler and  check whether the user accepted or declined the invitation...

    BOOL accept = (buttonIndex != alertView.cancelButtonIndex) ? YES : NO;

    // respond
    if(accept) 
//        void (^invitationHandler)(BOOL, MCSession *) = [self.arrayInvitationHandler objectAtIndex:0];
//        invitationHandler(accept, self.mySession);
    
    else
    
        NSLog(@"Session disallowed");
    


- (void)terminate 

    [self killExpireNotification];
    [self stopService];

@end

【问题讨论】:

【参考方案1】:

我已经解决了这个问题。对于每个有类似问题的人: 这不是 IPv6 的问题,而是如何使用 Multipeer 连接的问题。在我的案例中,我尝试使用 iPad 和模拟器进行 IPv6 连接。我用我的 Macbook 创建了一个nat64 network。以及模拟器和 iPad 从未见过彼此的原因是它们没有连接到同一个 wifi 网络。 解决方案: 只需测试两台 iPad 并将您的 mac 用作nat64 network 接入点。

【讨论】:

以上是关于ipv6的多人连接问题没有收到邀请的主要内容,如果未能解决你的问题,请参考以下文章

在多人连接中邀请对等方时偶尔崩溃

多人邀请的自定义通知

如何正确拆除多人连接会话?

多点连接 - 状态不变

在多人连接iOS 10中无法通过蓝牙连接

多对等连接:对等连接有时会失败:收到邀请响应,但我们从未向它发送邀请。中止