NSNetServiceBrowser didRemoveService занимает больше времени после открытия потока

У меня есть следующий код для обнаружения служб в сети:

[netServiceBrowser setDelegate: self]; 
[netServiceBrowser searchForServicesOfType: serviceType inDomain: domain];

Это приводит к вызовам этих двух методов (найти службу и удалить службу):

- (void) netServiceBrowser:(NSNetServiceBrowser*) netServiceBrowser 
         didFindService:(NSNetService*) netService ... {}

- (void) netServiceBrowser:(NSNetServiceBrowser*) netServiceBrowser 
         didRemoveService:(NSNetService*) netService ... {}

Это отлично работает. Когда я выключаю свое устройство, я сразу же получаю вызов didRemoveService.

Однако, когда я открываю поток (вход, выход или оба) для устройства:

[netService getInputStream: &inputStream outputStream: &outputStream];

[inputStream setDelegate: self];
[outputStream setDelegate: self];

[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
             forMode: NSDefaultRunLoopMode];
[inputStream open];

[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop]
              forMode:NSDefaultRunLoopMode];
[outputStream open];

NSNetServiceBrowser внезапно занимает почти минуту, чтобы обнаружить, что я выключил устройство
(для вызова didRemoveService требуется минута).

Устройства, с которыми я не общаюсь (открываю потоки), по-прежнему вызывают didRemoveService, как только я их удаляю.

Обновление: вот немного больше информации, связанной с моей проблемой.

Я провел трассировку с Wireshark и заметил следующее:

Я запускаю свое приложение в симуляторе iPad, приложение запускает NSNetServiceBrowser и обнаруживает принтер. После этого он открывает потоки ввода / вывода на устройство (через airport express, usb). Принтер отправляет мне обновления статуса, и когда я нажимаю кнопку тестирования в моем приложении, принтер начинает печатать. В Wireshark я вижу всю связь с принтером, как и ожидалось.

Теперь, когда я запускаю точно такое же приложение на iPad (и оставляю симулятор iPad включенным). Приложение также запускает NSNetServiceBrowser и обнаруживает принтер. Принтер не отправляет мне обновления статуса, и когда я нажимаю кнопку тестирования, принтер не печатает. В Wireshark я вижу связь. Принтер или аэропорт получает мои команды и отправляет пакет ACK.

Как только я убью приложение симулятора iPad, принтер начнет печатать команды, отправленные мной с помощью iPad. Кажется, что открытие сокета блокирует все события Bonjour, как я могу предотвратить это?

Больше здесь: https://devforums.apple.com/message/541436

2 ответа

Решение

Кажется, это ограничение Airport Express.

Моя текущая реализация с GCDAsyncSocket работает довольно хорошо, и я просто должен убедиться, что только один сокет используется для связи с Airport Express.

Я закрываю вопрос.

Я уверен, что в Lion обработчик больше не вызывается для события NSStreamEventEndEncountered. Итак, вам нужно закрыть входной поток и удалить его из цикла, когда вы уверены, что получили все данные. Например, когда происходит NSStreamEventHasBytesAvailable. Проверьте это, и я думаю, это должно работать

Другие вопросы по тегам