背景:
当你使用NsdManager
发现多个服务并尝试解析IP和端口时,只能解析一个服务。
可能原因:
- 竞争条件:如果你尝试同时解析多个服务,可能会出现竞争条件,导致只有一个解析成功。
- 服务解析限制:
NsdManager
可能在某一时刻只允许解析一个服务。 - 回调覆盖:如果你使用了同一个
ResolveListener
实例解析多个服务,可能会导致回调被覆盖,从而只处理最后一个解析的服务。
尝试方法:
-
1. 确保每个服务使用单独的
ResolveListener
实例: 每个服务解析请求应该有自己独立的ResolveListener
实例。 -
2. 逐一解析服务: 避免同时解析多个服务,而是一个接一个地解析,确保上一个解析完成后再开始下一个。
改动前的代码:
import android.;
import android.net.;
import ;
import ;
import ;
import .concurrent.Executor;
import .Executors;
public class NsdHelper {
private static final String TAG = "NsdHelper";
private NsdManager nsdManager;
private resolveListener;
public NsdHelper(Context context) {
nsdManager = (NsdManager) (Context.NSD_SERVICE);
}
public void resolveService(@NonNull NsdServiceInfo serviceInfo) {
Executor executor = ();
resolveListener = new () {
@Override
public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
(TAG, "Resolve failed: " + errorCode);
}
@Override
public void onServiceResolved(NsdServiceInfo serviceInfo) {
(TAG, "Service resolved: " + serviceInfo);
// Here you can get the resolved service details
String host = ().getHostAddress();
int port = ();
(TAG, "Host: " + host + ", Port: " + port);
}
};
(serviceInfo, executor, resolveListener);
}
}
改动后的代码:
以下是改进后的Kotlin代码示例,展示了如何处理多个服务的解析:
import
import
import
import
import
class NsdHelper(context: Context) {
private val nsdManager: NsdManager = (Context.NSD_SERVICE) as NsdManager
private val executor = ()
private val serviceQueue = mutableListOf<NsdServiceInfo>()
fun discoverServices() {
val discoveryListener = object : {
override fun onDiscoveryStarted(serviceType: String) {
(TAG, "Service discovery started")
}
override fun onServiceFound(serviceInfo: NsdServiceInfo) {
(TAG, "Service found: $serviceInfo")
// 将发现的服务添加到队列中等待解析
(serviceInfo)
if ( == 1) {
resolveNextService()
}
}
override fun onServiceLost(serviceInfo: NsdServiceInfo) {
(TAG, "Service lost: $serviceInfo")
(serviceInfo)
}
override fun onDiscoveryStopped(serviceType: String) {
(TAG, "Service discovery stopped")
}
override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
(TAG, "Service discovery start failed: $errorCode")
(this)
}
override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
(TAG, "Service discovery stop failed: $errorCode")
(this)
}
}
("_http._tcp.", NsdManager.PROTOCOL_DNS_SD, discoveryListener)
}
private fun resolveNextService() {
if (()) return
val serviceInfo = ()
val resolveListener = object : {
override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
(TAG, "Resolve failed: $errorCode")
(serviceInfo)
resolveNextService()
}
override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
(TAG, "Service resolved: $serviceInfo")
val host =
val port =
(TAG, "Host: $host, Port: $port")
(serviceInfo)
resolveNextService()
}
}
(serviceInfo, executor, resolveListener)
}
companion object {
private const val TAG = "NsdHelper"
}
}
代码解释:
- 服务队列:使用一个
MutableList
来保存发现的服务。 - 发现服务:通过
discoverServices
方法启动服务发现。 - 解析服务:在
onServiceFound
回调中,将发现的服务添加到队列中,并调用resolveNextService
方法开始解析。 - 逐一解析:
resolveNextService
方法从队列中取出第一个服务进行解析,并在解析完成或失败后解析下一个服务。
以上方式确保每次只解析一个服务,从而避免竞争条件和回调覆盖的问题。