Я пытаюсь выполнить обнаружение услуг на запатентованном аппаратном устройстве моей компании, которое имеет собственную WiFi-сеть и рекламирует услугу Bonjour в этой сети. Когда я подключаюсь к этой сети Wi-Fi, я использую NSD для обнаружения этой службы и ее разрешения.
Код довольно прост и в целом работает отлично и быстро. За исключением того, что у меня возникла довольно повторяющаяся проблема (~ 5 из 10 попыток), локализованная на моем Samsung S8 +. Пока что невозможно воспроизвести на S6 или Pixel XL.
Проблема в том, что DiscoveryListener никогда не делает ничего, кроме onDiscoveryStarted (), он просто работает вечно. Если я убиваю приложение и запускаю заново, иногда оно работает, иногда оно продолжает зависать.
Как будто есть заблокированный поток или что-то в этом роде, но в журналах нет полезной информации (которую я могу найти), и я ничего не нашел, чтобы зацепиться за нее, как то, что я могу сделать, чтобы восстановиться после этого.
Я добавил тайм-аут, который остановит слушателя через 30 секунд, но обычно после повторной попытки он все еще не работает.
Процесс обнаружения службы заключен в LiveData, который запускает его после активации.
const val SERVICE_TYPE_FOO = "_foo._tcp."
private val serviceDiscoveryListener = ServiceDiscoveryListener()
override fun onActive() {
super.onActive()
stopRunnable = StopDiscoveryRunnable()
nsdManager.discoverServices(
SERVICE_TYPE_FOO,
NsdManager.PROTOCOL_DNS_SD,
serviceDiscoveryListener
)
handler.postDelayed(stopRunnable, SERVICE_DISCOVERY_TIMEOUT_MS)
}
private lateinit var stopRunnable: Runnable
private inner class StopDiscoveryRunnable : Runnable {
override fun run() {
try {
nsdManager.stopServiceDiscovery(serviceDiscoveryListener)
Timber.w("service discovery timed out")
postValue(ServiceDiscoveryState.Error)
} catch (e: Throwable) {
// no-op
}
}
}
Слушатели очень простые ...
private inner class ServiceDiscoveryListener : NsdManager.DiscoveryListener {
override fun onServiceFound(serviceInfo: NsdServiceInfo?) {
if (serviceInfo != null) {
if (serviceInfo.serviceName.isNotEmpty() &&
serviceInfo.serviceName.containsFoo()
) {
nsdManager.resolveService(serviceInfo, ResolveListener())
handler.removeCallbacks(stopRunnable)
}
}
}
override fun onStopDiscoveryFailed(serviceType: String?, errorCode: Int) {
Timber.d("stop discovery failed")
nsdManager.stopServiceDiscovery(this)
postValue(ServiceDiscoveryState.Error)
}
override fun onStartDiscoveryFailed(serviceType: String?, errorCode: Int) {
Timber.d("start discovery failed")
nsdManager.stopServiceDiscovery(this)
postValue(ServiceDiscoveryState.Error)
}
override fun onDiscoveryStarted(serviceType: String?) {
Timber.d("discovery started")
}
override fun onDiscoveryStopped(serviceType: String?) {
Timber.d("discovery stopped")
}
override fun onServiceLost(serviceInfo: NsdServiceInfo?) {
Timber.d("discovery service lost")
postValue(ServiceDiscoveryState.Error)
}
}
private inner class ResolveListener : NsdManager.ResolveListener {
override fun onResolveFailed(serviceInfo: NsdServiceInfo?, errorCode: Int) {
Timber.d("resolve failed. errorCode = $errorCode")
if (errorCode != NsdManager.FAILURE_ALREADY_ACTIVE) {
Timber.d("not already active, so error")
postValue(ServiceDiscoveryState.Error)
} else {
Timber.d("already active")
}
}
override fun onServiceResolved(serviceInfo: NsdServiceInfo?) {
if (serviceInfo != null) {
Timber.d("resolved service: ${serviceInfo.serviceName} host: ${serviceInfo.host}:${serviceInfo.port} type: ${serviceInfo.serviceType}")
postValue(ServiceDiscoveryState.FooService(serviceInfo))
}
}
}
Мне не удалось найти большую ценность в журналах, хотя я видел это одно сообщение, когда что-то не работало. Попытки найти ответы на этот вопрос не принесли результатов.
04-26 13: 50: 14,541 953-1218 /? W // system / bin / netd: dnssd_clientstub DNSServiceProcessResult, вызванный с недопустимым DNSServiceRef 0x72bb818000 FFFFFFFF DDDDDDDD
Какую другую информацию я могу предоставить?
Я воспроизвел зависание, используя Bonjour Andriy Druk Service Browser пример кода на моем S8 +, который даже не использует NSD ... так что, возможно, проблема в основном коде mDNS а не специфично для реализации Google NSD?
Есть ли на S8 + системное программное обеспечение или раздувание, которое может мешать моему использованию NSD или mDNS - блокировка потоков или что-то в этом роде?