2011-07-06 30 views
21

我得到一个VOIP套接字在iOS应用程序的后台运行。iOS Voip套接字将不会在后台运行

我的连接工作正常,但是当我的应用程序进入后台也不会醒来。但是,如果我打开应用程序,它会响应它在睡觉时收到的任何消息。

设置我流像这样:

CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, 
            (CFStringRef) @"test.iusealocaltestserver.com", 
            5060, 
            &myReadStream, 
            &myWriteStream); 
CFReadStreamSetProperty ( myReadStream, 
          kCFStreamNetworkServiceType, 
          kCFStreamNetworkServiceTypeVoIP 
          ); 

CFSocketNativeHandle native; 
CFDataRef nativeProp = CFReadStreamCopyProperty(myReadStream, kCFStreamPropertySocketNativeHandle); 

CFDataGetBytes(nativeProp, CFRangeMake(0, CFDataGetLength(nativeProp)), (UInt8 *)&native); 
CFRelease(nativeProp); 

CFSocketRef theSocket = CFSocketCreateWithNative(kCFAllocatorDefault, native, 0, NULL, NULL); 

CFSocketGetContext(theSocket,&theContext);  


CFOptionFlags readStreamEvents = kCFStreamEventHasBytesAvailable | 
kCFStreamEventErrorOccurred  | 
kCFStreamEventEndEncountered | 
kCFStreamEventOpenCompleted; 

CFReadStreamSetClient(myReadStream, 
          readStreamEvents, 
          (CFReadStreamClientCallBack)&MyCFReadStreamCallback, 
         (CFStreamClientContext *)(&theContext)); 

CFReadStreamScheduleWithRunLoop(myReadStream, CFRunLoopGetCurrent(), 
           kCFRunLoopCommonModes); 

然后我的回调设置是这样的:

static void MyCFReadStreamCallback(CFReadStreamRef stream, CFStreamEventType type, void *pInfo); 

static void MyCFReadStreamCallback (CFReadStreamRef stream, CFStreamEventType type, void *pInfo) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSLog(@"Callback Happened"); 

    [pool release]; 
} 

“回调正巧”当我收到的数据获取调用和应用程序是打开,但如果应用程序最小化则不会。但是,当应用程序恢复时,它会处理收到的最小数据量。

我加入了VOIP标签的info.plist中。我的CFReadStreamSetProperty返回true。我在设备上运行而不是模拟器。它仍然不起作用,所以我不知道我的问题可能是什么。我可能只是做了一些愚蠢的事情,但几乎没有任何在线检查我的代码。

编辑:我无法测试任何的答案,因为我不再在这个项目上的工作,并没有进入到Mac/iOS版SDK。如果某个具有类似问题的人发现以下某个答案有用,请告诉我,我将对其进行最佳答案投票。

+0

+1:你还添加了“音频”标签中的plist?我只是从应用程序编程指南中阅读有关多任务处理的内容,但这看起来像是一些不规则的东西。希望你能得到答案。好问题。 –

+0

我还没有播放任何音频,所以不应该有所作为。但我仍然尝试过,并没有奏效。感谢至少给我一些尝试,我只是砸了我的头几个小时。 – Joel

+0

您可以将代码发布到您的保持活动超时处理程序吗? –

回答

28

如果你想要让在后台的VO​​IP应用程序运行,除了在plist文件的基础设置,您需要一个TCP套接字谁的属性设置为VOIP,比IOS系统会照顾这个插座你,当你的应用程序进入后台时,除tcp套接字外,每件事情都是'睡眠'。如果VOIP服务器发送一些认为是TCP套接字的数据,你的应用程序将唤醒10秒。在此期间,您可以发布本地通知。

只有TCP套接字可以设置为VOIP插槽。但是据我所知,大多数VOIP应用都基于UDP套接字。如果您不想将控制套接字与数据套接字分开。您应该创建另一个专注于唤醒您的应用程序的tcp套接字,并且从我个人的经验来看,很难保持这个'唤醒'信号和真正的sip控制信号同步,应用程序总是会错过sip邀请请求。

所以,最好的办法是从UDP数据插座分离SIP控制单一,使得它作为一个TCP套接字,这是最好的解决办法,但从来没有使用TCP套接字来传输语音数据。

另一个肮脏的方法:保持清醒的应用程序所有的时间。 正如我所说的,每个TCP单一应用程序接收认为“VOIP” TCP套接字,将继续申请清醒,持续10秒,所以在这个时间(后9秒)的结束,您可以发送到服务器的响应问对于另一个信号,当下一个信号到达时,应用程序将在9秒后再次唤醒,再次发送响应。继续这样做,你的应用程序将永远清醒。

+11

黄金知识 –

+0

@Joel:。你可以接收语音数据,而应用程序是在backgro运行UND。如果这篇文章有用,请在此更新并接受任何文章。 – User97693321

+0

我不确定你的意思是'在后台',如果应用程序完全在后台(不在调用中),只能接收到tcp数据。 –

0

您可能需要设置<key>UIBackgroundModes</key><array><string>audio</string></array>在Info.plist中,你需要确保音频会话活动/运行/不管你切换应用程序之前(假设是你会不会突然开始录制/播放音乐/不管什么时候你的应用程序在后台)。

The docs说,“音频”,您可以在后台播放音频,但想必这也适用于录制音频。如果它不起作用,您可以尝试几件事:

  • 设置“voip”和“audio”。
  • 玩沉默(这可能是最简单的与音频队列API)。
+0

玩沉默是苹果检测一招防止应用程序要在商店中发布(除非应用程序提供真实音频功能) – Albrecht

+0

一个VIOP插座将是一个真正的音频功能将不是吗?你有什么证据这种拒绝的?我从来没有见过的任何东西。 – Sneakyness

+0

从这个线程的第一个答案http://stackoverflow.com/questions/5840365/how-can-an-ios-app-keep-a-tcp-connection -alive-无限期,同时,在最backgro有一个应用程序的故事苹果被拒绝播放静默音频:https://web.archive.org/web/20140806111426/http://tapbots.com/blog/pastebot/pastebot-音乐在背景 – RenniePet

5

我坚持的完全相同的情况。
我的问题是,我已经配置了多个插座用作VoIP插座

你可以看到Apple's documentations about voip,他们说:
“配置应用程序的插座一个用于VoIP使用”

我猜他们是根据一个插槽仅唤醒您的应用程序。

提及的所有其他的东西仍然是正确的:

  • kCFStreamNetworkServiceTypeVoIP
  • '的info.plist' UIBackgroundModes:VOIP,音频
  • “信息。plist中” UIRequiresPersistentWifi关键
  • 将不会工作在模拟器
0

你在你的应用程序委托一个'applicationDidEnterBackground:'。我非常肯定,我已经阅读过某处(我找不到),您需要为ios定义它以识别您支持的背景模式。你不需要实现任何东西。

例如

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
} 
+0

这是刚刚从UIApplicationDelegate协议的方法,它是可选的和无关的这个问题 – gurooj

3

我也面临着同样的问题。但在我的情况下,一切工作正常,除非网络发生变化。我使用苹果“可达性”类来检测网络变化。如果应用程序在后台直到某个时候我的套接字工作,即使我手动切换我的网络以下。

  1. 无线网络 - > 3g的
  2. 科技3G - >无线

一段时间后,让又称手动我尝试网络交换机。没有什么是幸福,似乎我的应用程序没有检测到网络变化。我读了下面的苹果文档。我敢肯定做错了(或)disunderstood步骤3和6

有用于实施VoIP应用几个要求:

1.添加UIBackgroundModes关键看你的应用程序的Info.plist文件。将此密钥的值设置为包含voip字符串的数组。

  1. 配置用于VoIP使用的应用套接字之一。

  2. 之前移动到背景,调用setKeepAliveTimeout:处理程序:方法来安装将被定期地执行的处理程序。您的应用可以使用此处理程序来维护其服务连接。

  3. 配置音频会话处理过渡到和积极利用。

5.为了确保iPhone更好的用户体验,使用核心电话框架来调整相对于基于手机通话的行为负责;请参阅核心电话框架参考。

  1. 为了确保你的VoIP应用程序性能好,使用系统配置框架来检测网络的变化,让您的应用程序,以尽可能多地睡觉。
+0

我面临同样的问题。你有没有得到任何回电网络变化的原因?我认为当应用程序进入后台时,ios会将应用程序置于暂停状态,这就是为什么应用程序无法检测到网络更改。 –

相关问题