7

Tôi có đoạn code sau đây để khám phá các dịch vụ trên mạng:NSNetServiceBrowser didRemoveService mất nhiều thời gian sau khi mở dòng

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

Điều đó dẫn tới các cuộc gọi đến hai phương pháp này (tìm dịch vụ và loại bỏ dịch vụ):

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

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

Điều này hoạt động tốt. Khi tôi tắt thiết bị, tôi ngay lập tức nhận được cuộc gọi didRemoveService.

Tuy nhiên khi tôi mở một dòng (đầu vào, đầu ra hoặc cả hai) để các thiết bị:

[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]; 

Nó đột nhiên mất NSNetServiceBrowser gần một phút để phát hiện rằng tôi tắt thiết bị
(phải mất một phút cho didRemoveService để được gọi).

Thiết bị mà tôi không liên lạc với (mở luồng bằng) vẫn gọi didRemoveService ngay khi tôi xóa chúng.

Cập nhật: Dưới đây là một số thông tin khác liên quan đến vấn đề của tôi.

Tôi đã chạy một dấu vết với Wireshark và nhận thấy như sau:

tôi bắt đầu ứng dụng của tôi trong mô phỏng iPad, ứng dụng bắt đầu một NSNetServiceBrowser và phát hiện máy in. Sau đó, nó sẽ mở ra các luồng đầu vào/đầu ra vào thiết bị (thông qua dịch vụ đưa đón sân bay, usb). Máy in gửi cho tôi thông tin cập nhật trạng thái và khi tôi nhấn vào nút kiểm tra trong ứng dụng của tôi, máy in bắt đầu in. Trong Wireshark tôi thấy tất cả các giao tiếp với máy in như mong đợi.

Bây giờ, khi tôi bắt đầu chính xác ứng dụng tương tự trên iPad (và để chạy mô phỏngiPad đang chạy). Ứng dụng cũng bắt đầu NSNetServiceBrowser và phát hiện máy in. Máy in là không gửi cho tôi cập nhật trạng thái và khi tôi nhấn vào nút kiểm tra, máy in không in. Trong Wireshark tôi thấy thông tin liên lạc. Máy in hoặc sân bay nhận lệnh của tôi và gửi gói ACK.

Ngay khi tôi giết ứng dụng mô phỏng iPad, máy in bắt đầu in các lệnh mà tôi đã gửi bằng iPad. Dường như việc mở một ổ cắm chặn tất cả các sự kiện bonjour, làm thế nào tôi có thể ngăn chặn điều này xảy ra?

More đây: https://devforums.apple.com/message/541436

+0

Ngay khi tôi đóng luồng, didRemoveService sẽ kích hoạt. Có vẻ như đang chờ một thời gian chờ? – Zyphrax

+0

Tôi không chắc chắn nếu đây là trường hợp, nhưng hãy xem của bạn - (void) dòng: (NSStream *) aStream handleEvent: (NSStreamEvent) xử lý sự kiện. Trong Lion, trình xử lý không được gọi cho sự kiện NSStreamEventEndEncountered nữa. Vì vậy, bạn cần phải đóng luồng đầu vào của bạn và loại bỏ nó từ vòng lặp khi bạn chắc chắn rằng bạn đã nhận được tất cả các dữ liệu. Ví dụ: khi NSStreamEventHasBytesAvailable xảy ra. – Davyd

+0

Dành cho những người có quyền truy cập diễn đàn Apple Developer. Tôi đã đăng sự cố của mình ở đây: https://devforums.apple.com/message/541436. Thật không may vẫn không có giải pháp :( – Zyphrax

Trả lời

0

Nó có vẻ là một giới hạn của Airport Express.

Triển khai hiện tại của tôi với GCDAsyncSocket hoạt động khá tốt và tôi chỉ phải đảm bảo rằng chỉ một ổ cắm được sử dụng để giao tiếp với Airport Express.

Tôi đang đóng câu hỏi.

0

Tôi chắc chắn nó Trong Lion xử lý không được gọi cho sự kiện NSStreamEventEndEncountered nữa. Vì vậy, bạn cần phải đóng luồng đầu vào của bạn và loại bỏ nó từ vòng lặp khi bạn chắc chắn rằng bạn đã nhận được tất cả các dữ liệu. Ví dụ: khi NSStreamEventHasBytesAvailable xảy ra. Kiểm tra xem nó ra và tôi đoán nó sẽ làm việc

+0

Thật không may tôi phải giữ cho các luồng đầu vào của tôi mở để cập nhật thiết bị (máy in hết giấy, khay mở vv ..) Vấn đề này xảy ra trên Snow Leopard, iOS, Lion không thực sự quan trọng. – Zyphrax