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. Проверьте это, и я думаю, это должно работать