Android NSD - зависает / работает вечно - зависит от устройства? - PullRequest
0 голосов
/ 02 мая 2018

Я пытаюсь выполнить обнаружение услуг на запатентованном аппаратном устройстве моей компании, которое имеет собственную 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 - блокировка потоков или что-то в этом роде?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...