为什么NSNetServiceBrowser在iPhone OS中找到未发布的服务? [英] Why does NSNetServiceBrowser find unpublished services in iPhone OS?

查看:64
本文介绍了为什么NSNetServiceBrowser在iPhone OS中找到未发布的服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

构建我的移动应用程序的桌面版本,并为用户提供通过wifi进行同步的功能.一切都在模拟器中运行良好-解决网络服务(由桌面应用程序发布)或在服务不可用时发出通知都没有问题.

Building a desktop version of my mobile app and providing the user syncing over wifi. Everything works great in the simulator - no problems resolving net services (which are published by the desktop app) or noticing when services become unavailable.

问题是当我在电话上运行该应用程序时,服务被发现并解决(某种程度上),但是NSNetServiceBrowser永远不会注意到服务何时不可用.当发生这种情况时,网络服务浏览器会不断找到一个网络服务(不再发布)来解析它,但随后无法连接到该网络服务.经过几次失败的尝试之后,最终会调用服务浏览器委托的"didRemoveService",并且该应用开始重新正常运行.

The problem is when I run the app on the phone services are discovered and resolved (sometiems) but the NSNetServiceBrowser never notices when a service becomes unavailable. When this happens the net service browser constantly finds a net service (that is no longer published) resolves it but then can't connect to it. After several failed attempts the service browser delegate's "didRemoveService" is finally called and the app begins to behave correctly again.

我已经发布了代码,但是我发现在Apple的WiTap示例中也发生了同样的问题.服务已发布并被发现,但是一旦服务不可用,运行服务浏览器的客户端就不会更新-并反复尝试解析不应该"存在的服务.

I'd post my code but I've discovered the same issue is happening in Apple's WiTap example. Services are published and discovered but once they are made unavailable the client running the service browser doesn't update - and repeatedly tries to resolve a service that "shouldn't" exist.

我发现关闭wifi运行WiTap(所以Bonjour使用蓝牙)一切正常.我找不到抱怨WiTap无法正常工作的人,也找不到在线其他任何地方的此问题.有任何原因(可能是iPhone OS或我的无线网络)为什么网络服务浏览器可以找到并正确解析(但无法连接到)不可用的服务?

I've discovered that running WiTap with wifi turned off (so Bonjour uses bluetooth) everything works fine. I can't find anyone complaining about WiTap not working and can't find this issue anywhere else online. Any reason - possibly with iPhone OS or my wireless network - why a net service browser can find and correctly resolve (but can't connect to) services that are unavailable?

推荐答案

iPhone/iPod Touch上的Bonjour/NSNetServiceBrowser将同时使用Wifi和蓝牙进行服务发现-至少在受支持的设备上.每次您开始浏览服务时,它都会搜索WiFi和蓝牙(您可以在管理器的iPhone控制台中进行验证).由于您的模拟器设备"无法使用蓝牙,因此您的iPhone可以通过WiFi找到它.但是,如果您使用NSNetService在iPhone上发布,则同时也在WiFi 蓝牙上发布(如果支持和启用).当在支持BT的硬件上运行时,NSNetServiceBrowser会尽职地找到这两个实例,并通过委托回调报告这两个实例.

Bonjour/NSNetServiceBrowser on the iPhone/iPod Touch will utilize both Wifi and Bluetooth for service discovery--at least on supported devices. Each time you begin browsing for services, it will search both WiFi and Bluetooth (which you can verify in the iPhone's Console, in Organizer). Since your Simulator "device" cannot use Bluetooth, your iPhone discovers it over WiFi. However, if you are using NSNetService to publish on your iPhone, then you are publishing over both WiFi and Bluetooth as well (if supported and enabled). NSNetServiceBrowser, when running on BT-capable hardware, will dutifully find that both instances, and report both via delegate callbacks.

蓝牙PAN设置花费的时间比通过Wifi发布更长,因此,在发现并解决了所有基于Wifi的服务后,发现BT的服务通常显示良好.在测试两个真实设备时,我什至看到这两个服务都显示在我的UI中(通常仅在另一部手机崩溃后才显示).

Bluetooth PAN setup takes longer than publishing via Wifi, so the BT-discovered services often show up well after all the Wifi-based services have been discovered and resolved. When testing two real devices, I've even seen both services show up in my UI (usually only after the other phone crashes).

尽管如此,它确实使一些令人沮丧的编码成为可能.最好的选择是利用netService:didNotResolve:(i)重试解析,或(ii)使netService实例无效并等待另一部手机重新启动其应用程序.

It does make for some frustrating coding, though. Your best bet is to utilize netService:didNotResolve: to either (i) retry resolution, or (ii) invalidate the netService instance and wait for the other phone to relaunch their app.

此外,在其他几个方面也可能出错.由于提供给您的NSNetService实例是自动发布的,因此您需要保留它.大多数人将其添加到NSMutableArray或NSMutableDictionary中.如果是这种情况,请确保在添加对象之前已正确对其进行了初始化.由于发送到nil的消息完全可以,因此,如果将addObject:发送到nil,则看起来一切正常.除了不是.这在Bonjour故障排除中经常会出现,并且对我们所有人来说都是碰巧的.确保将您的NSNetService安排到一个正在运行的运行循环中,并以默认或通用模式运行.

Also, there are a couple of other areas things can go wrong. Since the NSNetService instance provided to you is autoreleased, you need to retain it. Most people add it to an NSMutableArray or NSMutableDictionary. If that's the case, make sure that you have properly initialized it before adding the object. Since messages to nil are perfectly ok, if you send addObject: to nil it will appear as though everything is working fine. Except that it isn't. This crops up very often in Bonjour troubleshooting, and happens to the best of us. Make sure that your NSNetService gets scheduled into an actively running runloop, and one that is running in default or common modes.

有一个与Apple归档的公开漏洞(截至09年10月4日),在这种情况下,Bonjour更新经常不会导致触发委托方法.我只在3GS上观察到这种情况.结果是客户端应用程序与网络不同步.

There is an open bug filed with Apple (as of 10/4/09) whereby every so often, a Bonjour update will not result in a delegate method getting fired. I have only observed this occurring on a 3GS. The result is a client app that is out of sync with the network.

NSNetServiceBrowser应该在服务离开网络时(在正常条件下)一致地通知.上面的错误只是一个间歇性错误,并且显然是特定于硬件的.如果您看到它持续发生,则可能是您的应用抛出了异常.如果您使用后台线程,则可以在不导致整个应用程序崩溃的情况下发生这种情况.您可能需要检查iPhone控制台并记录错误消息.确保已在符号objc_exception_throw上设置了一个断点.

NSNetServiceBrowser should consistently notify when a service leaves the network (under nominal conditions). The bug above is only an intermittent one, and apparently, hardware specific. If you see it occurring consistently, then it's likely that your app is throwing an exception. If you are using background threads, this can occur without causing your whole app to crash. You may want to check your iPhones Console and logs for error messages. Make sure you have set a breakpoint on the symbol objc_exception_throw.

这是我发现的另一条故障排除提示,非常宝贵.使用以下命令通过Terminal监视Bonjour在您的开发机上的广播:dns-sd -B _serviceName.这样一来,您就可以查看本地网络上所有服务的来龙去脉.如果您的应用程序退出,但是dns-sd没有显示Remove事件,那么您的代码需要重新访问.如果dns-sd显示删除事件,但您的其他应用未正确处理该事件,则可能会看到上述错误.也可能是您的代码没有按照您认为的那样做.请记住,这只会帮助您对Wifi到Wifi服务Bonjour进行故障排除. iPhone模拟器不支持从蓝牙到蓝牙.

Here's another troubleshooting tip that I've found invaluable. Monitor Bonjour broadcasts on your dev machine via Terminal using the following command: dns-sd -B _serviceName. This will let you see all comings and goings on your local network for your service. If your app quits, but dns-sd does not show a Remove event, then your code needs revisiting. If dns-sd shows a remove event, but your other apps don't process it correctly, you may be seeing the above mentioned bug. It may also be the case that your code isn't doing what you think it's doing. And remember, this will only help you troubleshoot Wifi-to-Wifi service Bonjour. Bluetooth to Bluetooth is not supported from the iPhone Simulator.

阅读全文,问题排查iPhone上的Bonjour Networking ,在我的开发博客中.

Read the full article, Troubleshooting Bonjour Networking for the iPhone, at my dev blog.

这篇关于为什么NSNetServiceBrowser在iPhone OS中找到未发布的服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆