NSNetServiceBrowser didRemoveService занимает больше времени после открытия потока - PullRequest
7 голосов
/ 23 августа 2011

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

[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 и обнаруживает принтер. После этого он открывает потоки ввода / вывода на устройство (через аэропорт экспресс, usb). принтер отправляет мне обновления статуса, и когда я нажимаю кнопку тестирования в мое приложение принтер начинает печатать. В Wireshark я вижу все связь с принтером, как и ожидалось.

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

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

Подробнее здесь: https://devforums.apple.com/message/541436

Ответы [ 2 ]

0 голосов
/ 01 августа 2012

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

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

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

0 голосов
/ 01 декабря 2011

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

...