iPhone OS 4.x - фоновые TCP-сокеты не отвечают - PullRequest
2 голосов
/ 10 августа 2010

Я пытаюсь реализовать фоновый режим для приложения VoIP, используя новые механизмы, предоставляемые iPhone OS 4.x

Все еще безуспешно ... Приложение хранит молчание в фоновом режиме, когда некоторые данные поступают с сервера через сокет TCP.

Согласно документации необходимо выполнить следующие две вещи:

  1. Добавить voip значение для Required background modes в Info.plst файл
  2. Установить для свойства kCFStreamNetworkServiceType из CFReadStreamRef объекта значение kCFStreamNetworkServiceTypeVoIP

Я использую внешний BSD-сокет для создания экземпляра CFReadStreamRef с функцией CFStreamCreatePairWithSocket. Ручка розетки правильная - проверено с некоторыми испытаниями. Итак, я получаю правильный CFReadStreamRef объект, который позже настраиваю и открываю.

Вот кусок кода:

CFSocketNativeHandle socket = (CFSocketNativeHandle)socketHandle; 
CFStreamCreatePairWithSocket(kCFAllocatorDefault, socket, &sipSocketReadStream, nil);
CFReadStreamSetProperty(sipSocketReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
NSInputStream *inputStream = (NSInputStream*)sipSocketReadStream;   
[inputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
CFReadStreamOpen(sipSocketReadStream);

Обратите внимание - мой делегат на NSInputStream успешно получает Stream Opened событие. Но никаких других событий просто не было - я ожидал получить событие, когда начал приходить некоторый TCP-трафик.

Ответы [ 3 ]

4 голосов
/ 01 октября 2010

Я должен повторить совет мудреца, упомянутый Гиладом. Фоновые TCP-сокеты НЕ работают на симуляторе. Я потратил довольно много времени, пытаясь разобраться в этой проблеме, поглощенной удобством симулятора.

Кроме того, и, может быть, это только я, я не понял из документации, какое значение является ключом, а какое - свойством. Для справки, вот как я его установил и он работает:

res = [oStream setProperty:NSStreamNetworkServiceTypeVoIP 
                    forKey:NSStreamNetworkServiceType];

if(!res){
   // Error handling here
}
2 голосов
/ 16 сентября 2010

Вы должны убедиться, что у вас есть UIBackgroundModes как массив, с опцией voip в вашем файле plist:

<key>UIBackgroundModes</key>
<array>
    <string>voip</string>
</array>

Кроме того, voip фоновые задачи НЕ работают под симулятором, поэтому убедитесь, что вы тестируете на реальном устройстве. Если вы правильно установили UIBackgroundModes и установили тип потока на kCFStreamNetworkServiceTypeVoIP, то я могу только сделать вывод, что вы, вероятно, тестируете с помощью симулятора.

0 голосов
/ 09 января 2013

Мне кажется, вы пропустили [inputStream open] . Как только откроете поток, я надеюсь, что вы получите вызов для вашего метода делегата.

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent

После успешного TCP-соединения в режиме VOIP только iOS поддерживает ваш сокет, даже если приложение работает в фоновом режиме.

...