首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的MCSession对等方随机断开连接?

为什么我的MCSession对等方随机断开连接?
EN

Stack Overflow用户
提问于 2013-09-22 01:07:52
回答 5查看 11.1K关注 0票数 41

我正在使用MCNearbyServiceBrowser和MCNearbyServiceAdvertiser将两个对等体加入到MCSession中。我可以使用MCSession的sendData方法在它们之间发送数据。在我通过会话的MCSessionDelegate didChangeState处理程序随机(而不是由于我控制的任何事件)接收到MCSessionStateNotConnected之前,一切似乎都像预期的那样工作。此外,MCSession的connectedPeers数组不再有我的同级。

两个问题:为什么?如何防止MCSession断开连接?

EN

回答 5

Stack Overflow用户

发布于 2013-10-31 07:59:03

这是一个bug,我刚刚报告给了苹果。文档声称didReceiveCertificate回调是可选的,但事实并非如此。将此方法添加到MCSessionDelegate

代码语言:javascript
复制
- (void) session:(MCSession *)session didReceiveCertificate:(NSArray *)certificate fromPeer:(MCPeerID *)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler
 {
     certificateHandler(YES);
 }

随机断开应该会停止。

票数 27
EN

Stack Overflow用户

发布于 2013-10-21 23:26:21

更新在使用苹果的支持票证后,他们确认,调用sendData的频率太高,数据太多会导致连接断开。

当命中断点和背景时,我会断开连接。由于断点不会发生在应用程序商店上,因此您需要通过在应用程序即将进入后台时开始一个后台任务来处理后台情况。然后在应用程序返回前台时结束此任务。在iOS 7上,这为你提供了大约3分钟的后台时间,这总比什么都没有好。

一个额外的策略是使用[[UIApplication sharedApplication] backgroundTimeRemaining]在你的后台时间到期之前安排一个大约15秒的本地通知,这样你就可以在应用程序暂停和关闭多点框架之前将用户带回应用程序。也许本地通知会警告他们,他们的会话将在10秒内到期或其他什么……

如果后台任务到期,而应用程序仍在后台,则必须拆除与多点连接相关的所有内容,否则将会崩溃。

代码语言:javascript
复制
- (void) createExpireNotification
{
    [self killExpireNotification];

    if (self.connectedPeerCount != 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];
        self.expireNotification = n;
        self.expireNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:msgTime];
        self.expireNotification.alertBody = TR(@"Text_MultiPeerIsAboutToExpire");
        self.expireNotification.soundName = UILocalNotificationDefaultSoundName;
        self.expireNotification.applicationIconBadgeNumber = 1;

        [UIApplication.sharedApplication scheduleLocalNotification:self.expireNotification];
    }
}

- (void) killExpireNotification
{
    if (self.expireNotification != nil)
    {
        [UIApplication.sharedApplication cancelLocalNotification:self.expireNotification];
        self.expireNotification = nil;
    }
}

- (void) applicationWillEnterBackground
{
    self.taskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
    {
        [self shutdownMultiPeerStuff];
        [[UIApplication sharedApplication] endBackgroundTask:self.taskId];
        self.taskId = UIBackgroundTaskInvalid;
    }];
    [self createExpireNotification];
}

- (void) applicationWillEnterForeground
{
    [self killExpireNotification];
    if (self.taskId != UIBackgroundTaskInvalid)
    {
        [[UIApplication sharedApplication] endBackgroundTask:self.taskId];
        self.taskId = UIBackgroundTaskInvalid;
    }
}

- (void) applicationWillTerminate
{
    [self killExpireNotification];
    [self stop]; // shutdown multi-peer
}

由于苹果的bug,你也需要在你的MCSession委托中使用这个处理程序:

代码语言:javascript
复制
- (void) session:(MCSession*)session didReceiveCertificate:(NSArray*)certificate fromPeer:(MCPeerID*)peerID certificateHandler:(void (^)(BOOL accept))certificateHandler
 {
     if (certificateHandler != nil) { certificateHandler(YES); }
 }
票数 18
EN

Stack Overflow用户

发布于 2014-02-05 05:32:18

造成这种情况的原因很多,根据我的经验,到目前为止,这两个答案都是正确的。你会在其他类似的问题中发现的另一个问题是:只有一个对等点可以接受另一个对等点的邀请

因此,为了澄清,如果你设置了一个所有设备都既是广告商又是浏览器的应用程序,任何设备都可以自由地邀请任何其他人加入会话。但是,在任意两台给定设备之间,只有一台设备可以实际接受邀请并连接到另一台设备。如果两个设备都接受对方的邀请,它们将在一分钟或更短时间内断开连接。

请注意,此限制不会阻止所需的行为,因为-不像我在构建多点实现之前的直觉所说的那样-当一个设备接受邀请并连接到另一个设备时,它们都变得已连接并接收连接委托方法,并且可以相互发送消息。

因此,如果您连接的是浏览和广告的设备,请自由发送邀请,但只接受其中之一。

只接受两个邀请中的一个的问题可以有无数种方法来解决。首先,您可以将任意对象或字典(存档为数据)作为context参数传递到邀请中。因此,两个设备都可以访问对方的任何任意信息(当然还有自身)。因此,您至少可以使用以下策略:

  • 只需compare: peerID的显示名称即可。但不能保证它们不会相等。
  • 存储你的多点控制器初始化的日期,并为每个对等点使用一个UUID,然后发送它进行比较(我的技术是,每个设备--实际上是设备上的每个用户--都有一个持久的UUID it employs).
  • etc --任何同时支持NSCoding和compare:的对象都可以。
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18935288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档