2016-02-18 4 views
9

अंतिम सप्ताह के पाठ्यक्रम में, Android के एनएसडी कार्यान्वयन मुझे पागल हो जाना बना रही है:एंड्रॉयड, एनएसडी/DNS-SD: NsdManager अविश्वसनीय खोज और आईपी संकल्प

देखने के एक उपयोगकर्ता के दृष्टिकोण से, निम्नलिखित में समस्या आने पर:

  • डिवाइस एक दूसरे को पूरी तरह से गैर-निर्धारक फैशन में खोजते हैं। अगर मैं अपना NsdManager-आधारित ऐप लॉन्च करता हूं, तो यह केवल दो डिवाइस शामिल होने पर कम या ज्यादा काम करता है। यदि कोई तीसरा डिवाइस जुड़ता है, तो यह शायद ही कभी पहले दो को खोजेगा, और पहले दो तीसरे को नहीं देखेंगे। अगर मैं ऐप्स से बाहर निकलता हूं (वे एनएसडी श्रोताओं को गर्व से अनियंत्रित करते हैं) और उन्हें एक अलग क्रम में पुनरारंभ करें, तो खोज पैटर्न बिल्कुल समान नहीं है, लेकिन समान है।

  • मेरे घर नेटवर्क में, खोजे गए उपकरणों का आईपी रिज़ॉल्यूशन मूल रूप से अपेक्षित रूप से काम करता है। काम पर, कभी-कभी जब केवल दो डिवाइस (ए और बी) का उपयोग करते हैं, डिवाइस ए ए के आईपी पते और बी के पोर्ट के साथ डिवाइस बी की सेवा को हल करेगा और इसके विपरीत। तो किसी भी तरह से आईपी पता और सेवा का नाम निचले स्तर पर संभवतः मिश्रित हो जाता है (शायद एनएसडीमेनगर)।

मैं अब इस (https://code.google.com/p/android/issues/detail?id=201314&thanks=201314&ts=1455814995) के लिए गूगल कोड पर एक बग रिपोर्ट दायर किया है। मैं यहां भी अधिक प्रतिक्रिया प्राप्त करने की उम्मीद में इसे पोस्ट कर रहा हूं; शायद मुझे अपने एनएसडी सहायक वर्ग में कुछ मिला है।

सबसे पहले, अंतहीन डिबगिंग के बाद, मुझे अब लॉगबैक में संकेत मिले हैं कि एंड्रॉइड के अंतर्निहित NsdService स्वयं खराब हो सकते हैं, जबकि एमडीएनएसडीएस सही तरीके से काम करता प्रतीत होता है। लेकिन मैं अनिश्चित हूँ ...

यहाँ है कि समस्या (कुछ संदेश पठनीयता के लिए फ़िल्टर किए गए) को दिखाता है कुछ लॉग उत्पादन है:

  • मेरे एनएसडी सेवा:

    02-18 16:57:02.327: D/NsdService(628): startMDnsDaemon 
    02-18 16:57:02.327: D/MDnsDS(187): Starting MDNSD 
    02-18 16:57:02.529: D/NsdService(628): New client listening to asynchronous messages 
    02-18 16:57:02.529: D/NsdService(628): New client, channel: [email protected] messenger: [email protected] 
    02-18 16:57:02.532: D/NsdService(628): Register service 
    02-18 16:57:02.532: D/NsdService(628): registerService: 106 name: TuSync-0.57392, type: _tusync._tcp., host: /::, port: 57392 
    02-18 16:57:02.533: D/MDnsDS(187): serviceRegister(106, (null), TuSync-0.57392, _tusync._tcp., (null), (null), 57392, 0, <binary>) 
    02-18 16:57:02.533: D/MDnsDS(187): serviceRegister successful 
    02-18 16:57:02.534: D/NsdService(628): Register 1 106 
    02-18 16:57:04.083: D/MDnsDS(187): register succeeded for 106 as TuSync-0.57392 
    02-18 16:57:04.087: D/NsdService(628): SERVICE_REGISTERED Raw: 606 106 "TuSync-0.57392" 
    02-18 16:57:04.109: D/NsdService(628): Discover services 
    02-18 16:57:04.109: D/NsdService(628): discoverServices: 107 _tusync._tcp. 
    02-18 16:57:04.110: D/MDnsDS(187): discover((null), _tusync._tcp., (null), 107, 0) 
    02-18 16:57:04.110: D/MDnsDS(187): discover successful 
    02-18 16:57:04.110: D/NsdService(628): Discover 2 107_tusync._tcp. 
    02-18 16:57:04.333: D/MDnsDS(187): Discover found new serviceName TuSync-0.57392, regType _tusync._tcp. and domain local. for 107 
    02-18 16:57:04.334: D/NsdService(628): SERVICE_FOUND Raw: 603 107 "TuSync-0.57392" _tusync._tcp. local. 
    02-18 16:57:04.338: D/NsdService(628): Resolve service 
    02-18 16:57:04.338: D/NsdService(628): resolveService: 108 name: TuSync-0.57392, type: _tusync._tcp., host: null, port: 0 
    02-18 16:57:04.339: D/MDnsDS(187): resolveService(108, (null), TuSync-0.57392, _tusync._tcp., local.) 
    02-18 16:57:04.345: D/MDnsDS(187): startMonitoring 108 
    02-18 16:57:04.345: D/MDnsDS(187): resolveService successful 
    02-18 16:57:04.346: D/MDnsDS(187): resolve succeeded for 108 finding TuSync-0\.57392._tusync._tcp.local. at Android-3.local.:57392 with txtLen 1 
    02-18 16:57:04.347: D/NsdService(628): SERVICE_RESOLVED Raw: 608 108 "TuSync-0\\.57392._tusync._tcp.local." "Android-3.local." 57392 1 
    02-18 16:57:04.347: D/NsdService(628): stopResolveService: 108 
    02-18 16:57:04.347: D/MDnsDS(187): Stopping resolve with ref 0xb5c4734c 
    02-18 16:57:04.349: D/NsdService(628): getAdddrInfo: 109 
    02-18 16:57:04.349: D/MDnsDS(187): getAddrInfo(109, (null) 0, Android-3.local.) 
    02-18 16:57:04.350: D/MDnsDS(187): getAddrInfo successful 
    02-18 16:57:04.352: D/MDnsDS(187): getAddrInfo succeeded for 109: 109 "Android-3.local." 120 10.0.0.4 
    02-18 16:57:04.352: D/MDnsDS(187): getAddrInfo succeeded for 109: 109 "Android-3.local." 120 fe80::204:4bff:fe2c:6c87 
    02-18 16:57:04.354: D/NsdService(628): SERVICE_GET_ADDR_SUCCESS Raw: 612 109 "Android-3.local." 120 10.0.0.4 
    02-18 16:57:04.354: D/NsdService(628): stopGetAdddrInfo: 109 
    02-18 16:57:04.355: D/MDnsDS(187): Stopping getaddrinfo with ref 0xb5c472d4 
    02-18 16:57:04.364: E/NsdService(628): Unique id with no client mapping: 109 
    02-18 16:57:04.364: E/NsdService(628): Unhandled { when=-10ms what=393242 [email protected] target=com.android.internal.util.StateMachine$SmHandler } 
    02-18 16:57:04.627: D/MDnsDS(187): Discover found new serviceName TuSync-0.36230, regType _tusync._tcp. and domain local. for 107 
    02-18 16:57:04.632: D/MDnsDS(187): Discover found new serviceName TuSync-0.60493, regType _tusync._tcp. and domain local. for 107 
    02-18 16:57:04.633: D/NsdService(628): SERVICE_FOUND Raw: 603 107 "TuSync-0.36230" _tusync._tcp. local. 
    02-18 16:57:04.634: D/NsdService(628): SERVICE_FOUND Raw: 603 107 "TuSync-0.60493" _tusync._tcp. local. 
    02-18 16:57:04.635: D/NsdService(628): Resolve service 
    02-18 16:57:04.635: D/NsdService(628): resolveService: 110 name: TuSync-0.36230, type: _tusync._tcp., host: null, port: 0 
    02-18 16:57:04.636: D/MDnsDS(187): resolveService(110, (null), TuSync-0.36230, _tusync._tcp., local.) 
    02-18 16:57:04.637: D/MDnsDS(187): resolve succeeded for 110 finding TuSync-0\.36230._tusync._tcp.local. at Android.local.:36230 with txtLen 1 
    02-18 16:57:04.638: D/NsdService(628): Resolve service 
    02-18 16:57:04.638: D/NsdService(628): SERVICE_RESOLVED Raw: 608 110 "TuSync-0\\.36230._tusync._tcp.local." "Android.local." 36230 1 
    02-18 16:57:04.639: D/NsdService(628): stopResolveService: 110 
    02-18 16:57:04.639: D/MDnsDS(187): Stopping resolve with ref 0xb5c473c4 
    02-18 16:57:04.643: D/MDnsDS(187): getAddrInfo succeeded for 111: 111 "Android.local." 120 10.0.0.5 
    02-18 16:57:04.643: D/MDnsDS(187): getAddrInfo succeeded for 111: 111 "Android.local." 120 fe80::204:4bff:fe26:8483 
    02-18 16:57:04.644: D/NsdService(628): SERVICE_GET_ADDR_SUCCESS Raw: 612 111 "Android.local." 120 10.0.0.5 
    02-18 16:57:04.644: D/NsdService(628): stopGetAdddrInfo: 111 
    02-18 16:57:04.645: D/MDnsDS(187): Stopping getaddrinfo with ref 0xb5c47364 
    02-18 16:57:04.645: D/MDnsDS(187): Going to poll with pollCount 3 
    02-18 16:57:04.658: E/NsdService(628): Unique id with no client mapping: 111 
    02-18 16:57:04.658: E/NsdService(628): Unhandled { when=-14ms what=393242 [email protected] target=com.android.internal.util.StateMachine$SmHandler } 
    

    संदर्भ पर कुछ नोट प्रकार _tusync._tcp है।

  • मैं TuSync-0 प्रारूप में सभी नोड्स के लिए अद्वितीय सेवा नाम बनाता हूं। [स्थानीय पोर्ट नंबर] नामकरण विवादों को रोकने और डिबगिंग को कम करने के लिए।
  • इस परीक्षण परिदृश्य में, तीन डिवाइस हैं। लॉगिंग उपकरण के IP, 10.0.0.4 है बंदरगाह 57392.

लॉग शो, कि अंतर्निहित MDnsDS डेमॉन को सही ढंग से पता चलता है और सभी नोड्स हल करता है। हालांकि, ऊपर NsdService उन सभी के लिए संकल्प का प्रचार नहीं करता है। 16: 57: 04.627 पर एक आईडी टकराव प्रतीत होता है, जहां दोनों डिवाइस के साथियों (TuSync-0.36230 और TuSync-0.60493) को 107 की आंतरिक आईडी असाइन की जाती है (यदि मैं लॉग को देखकर सही ढंग से तंत्र की व्याख्या करता हूं) । discoveryListener मैं NsdManager के साथ पंजीकृत दोनों नोड्स की खोज पर सूचित किया जाता है, हालांकि, को हल करने उनमें से केवल एक के लिए काम करता है, अन्य एक त्रुटि से चलाता है:

02-18 16:57:04.638: E/NsdHelper(6370): Resolve failed with error code: 
3. Service: name: TuSync-0.60493, type: _tusync._tcp., host: null, port: 0 

मैं भी अतिरिक्त मामलों का अनुभव किया है जहां, के बाद NsdService लॉग में "SERVICE_FOUND रॉ" संदेश उत्सर्जित करता है, मेरी खोज श्रोता को अधिसूचित नहीं किया जाता है।एक अनुकरणीय लॉग (बहुत ज़्यादा फिल्टर, एक ही परीक्षण सेटअप जैसा कि ऊपर):

02-18 17:54:06.692: D/MDnsDS(187): Starting MDNSD 
02-18 17:54:06.896: D/NsdService(628): registerService: 112 name: TuSync-0.57392, type: _tusync._tcp., host: /::, port: 57392 
02-18 17:54:06.896: D/MDnsDS(187): serviceRegister(112, (null), TuSync-0.57392, _tusync._tcp., (null), (null), 57392, 0, <binary>) 
02-18 17:54:06.896: D/MDnsDS(187): serviceRegister successful 
02-18 17:54:08.802: D/NsdService(628): SERVICE_REGISTERED Raw: 606 112 "TuSync-0.57392" 
02-18 17:54:08.820: D/NsdService(628): Discover services 
02-18 17:54:09.050: D/MDnsDS(187): Discover found new serviceName TuSync-0.57392, regType _tusync._tcp. and domain local. for 113 
02-18 17:54:09.050: D/NsdService(628): SERVICE_FOUND Raw: 603 113 "TuSync-0.57392" _tusync._tcp. local. 
02-18 17:54:09.211: D/MDnsDS(187): Discover found new serviceName TuSync-0.60493, regType _tusync._tcp. and domain local. for 113 
02-18 17:54:09.212: D/NsdService(628): SERVICE_FOUND Raw: 603 113 "TuSync-0.60493" _tusync._tcp. local. 
02-18 17:54:09.215: D/NsdService(628): resolveService: 116 name: TuSync-0.60493, type: _tusync._tcp., host: null, port: 0 
02-18 17:54:09.216: D/MDnsDS(187): resolveService(116, (null), TuSync-0.60493, _tusync._tcp., local.) 
02-18 17:54:09.217: D/MDnsDS(187): resolve succeeded for 116 finding TuSync-0\.60493._tusync._tcp.local. at Android-2.local.:60493 with txtLen 1 
02-18 17:54:09.219: D/NsdService(628): SERVICE_RESOLVED Raw: 608 116 "TuSync-0\\.60493._tusync._tcp.local." "Android-2.local." 60493 1 
02-18 17:54:09.228: D/MDnsDS(187): getAddrInfo succeeded for 117: 117 "Android-2.local." 120 10.0.0.6 
02-18 17:54:09.228: D/MDnsDS(187): getAddrInfo succeeded for 117: 117 "Android-2.local." 120 fe80::c643:8fff:fec5:5648 
02-18 17:54:09.229: D/NsdService(628): SERVICE_GET_ADDR_SUCCESS Raw: 612 117 "Android-2.local." 120 10.0.0.6 
02-18 17:54:09.244: D/MDnsDS(187): Discover found new serviceName TuSync-0.36230, regType _tusync._tcp. and domain local. for 113 
02-18 17:54:09.251: E/NsdService(628): Unique id with no client mapping: 117 
02-18 17:54:09.251: E/NsdService(628): Unhandled { when=-22ms what=393242 [email protected] target=com.android.internal.util.StateMachine$SmHandler } 
02-18 17:54:09.255: D/NsdService(628): SERVICE_FOUND Raw: 603 113 "TuSync-0.36230" _tusync._tcp. local. 

इस मामले में, खोज की सहकर्मी 10.0.0.5 (बंदरगाह 36,230) कोई discoveryListener अधिसूचना से चलाता है। अंतिम लॉग संदेश के बाद, कुछ भी नहीं होता है। तो मेरे लॉगिंग नोड 10.0.0.4 ने केवल एक अन्य सहकर्मी की खोज की, 10.0.0.6:60493।

समान बग रिपोर्ट की कम मात्रा मुझे आश्चर्य है कि अगर मैं इन समस्याओं के साथ या यदि NsdManager पूरी तरह से अस्थिर है और कोई भी इसे इस्तेमाल करता है केवल एक ही कर रहा हूँ बनाता है?

संदर्भ के लिए, यहां मेरे सहायक वर्ग का कोड है - यह एंड्रॉइड एनएसडी चैट ट्यूटोरियल के समान है, लेकिन मैंने इसे सुधारने की कोशिश की क्योंकि ट्यूटोरियल कुछ अन्य बग्स को उत्तेजित करता है।

public final class NsdHelper { 

    public static final String TAG = "NsdHelper"; 

    private final Context mContext; 

    private final NsdManager mNsdManager; 

    private final String mBaseServiceName; // Base component of the service name, e.g. "service_xy" 
    private String mServiceName; // Service name of the local node, may be updated upon peer detection with service name conflicts, e.g. to "service_xy (2)" 
    private final String mServiceType; 

    private final NsdHandler mNsdHandler; 

    private MyRegistrationListener mRegistrationListener; 
    private final Object mRegistrationLock = new Object(); 

    private MyDiscoveryListener mDiscoveryListener; 
    private final Object mDiscoveryLock = new Object(); 

    private final Object mResolveLock = new Object(); 
    private final Semaphore mResolveSemaphore; 

    public NsdHelper(Context context, String baseServiceName, String serviceName, String serviceType, NsdHandler nsdHandler) { 
     mContext = context; 
     mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); 
     mNsdHandler = nsdHandler; 
     mBaseServiceName = baseServiceName; 
     mServiceName = serviceName; 
     mServiceType = serviceType; 

     mResolveSemaphore = new Semaphore(10, true); 
    } 

    /********************* 
    * Lifecycle methods * 
    *********************/ 

    public void registerLocalService(final int port) { 

     NsdServiceInfo localServiceInfo = new NsdServiceInfo(); 
     localServiceInfo.setServiceName(mServiceName); 
     localServiceInfo.setServiceType(mServiceType); 
     localServiceInfo.setPort(port); 

     synchronized (mRegistrationLock) { 
      if (mRegistrationListener == null) { 
       mRegistrationListener = new MyRegistrationListener(); 
       // try { 
       mNsdManager.registerService(
         localServiceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener); 

       /*} catch (Exception e) { 
        MLog.e(TAG, "Exception registering service; trying to unregister.", e); 
        unregisterLocalService(); 

        mNsdHandler.onRegistrationFailed(localServiceInfo, 0); 
       }*/ 
      } else { 
       MLog.w(TAG, "registerLocalService called while service registration already in progress or service already registered."); 
      } 
     } 
    } 

    public void unregisterLocalService() { 
     synchronized (mRegistrationLock) { 
      if (mRegistrationListener != null) { 
       // try { 
        mNsdManager.unregisterService(mRegistrationListener); 
       /*} catch (IllegalArgumentException e) { 
        MLog.w(TAG, "Exception trying to unregister registrationListener."); 
       }*/ 
       mRegistrationListener = null; 
      } else { 
       MLog.w(TAG, "unregisterLocalService called while service not yet registered or already unregistered."); 
      } 
     } 
    } 

    public void startDiscovery() { 
     synchronized(mDiscoveryLock) { 
      if(mDiscoveryListener == null) { 
       mDiscoveryListener = new MyDiscoveryListener(); 
       mNsdManager.discoverServices(
         mServiceType, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); 
      } else { 
       MLog.w(TAG, "StartDiscovery called while discovery is already in progress."); 
      } 
     } 
    } 

    public void stopDiscovery() { 
     synchronized (mDiscoveryLock) { 
      if (mDiscoveryListener != null) { 
       mNsdManager.stopServiceDiscovery(mDiscoveryListener); 
       mDiscoveryListener = null; 
      } else { 
       MLog.w(TAG, "StopDiscovery called while no discovery is in progress."); 
      } 
     } 
    } 

    public void tearDown() { 
     MLog.v(TAG, "NsdHelper: tearDown()"); 
     stopDiscovery(); 
     unregisterLocalService(); // TODO this causes an exception, when the listener is already unregistered 
    } 

    /** 
    * Returns the current service name of the service. 
    * @return 
    */ 
    public String getServiceName() { 
     return mServiceName; 
    } 

    /** 
    * Convenience method to initiate service resolution 
    * @param serviceInfo NsdServiceInfo object for the service to be resolved 
    */ 
    private void resolveService(NsdServiceInfo serviceInfo) { 
     try { 
      MLog.vv(TAG, "Resolving service: acquiring semaphore."); 
      mResolveSemaphore.acquire(); 
      MLog.vv(TAG, "Resolving service: semaphore acquired."); 
     } catch (InterruptedException e) { 
      MLog.w(TAG, "resolveService: Waiting for acquisition of semaphore interrupted."); 
     } 
     mNsdManager.resolveService(serviceInfo, new MyResolveListener(serviceInfo.getServiceName())); 
    } 

    /************* 
    * Listeners * 
    *************/ 

    private class MyDiscoveryListener implements NsdManager.DiscoveryListener { 

     @Override 
     public void onDiscoveryStarted(String regType) { 
      MLog.d(TAG, "Service discovery started"); 
      mNsdHandler.onDiscoveryStarted(); 
     } 

     @Override 
     public void onServiceFound(NsdServiceInfo serviceInfo) { 
      MLog.d(TAG, "Discovered service: " + serviceInfo); 

      // Protocol matches? 
      if (!serviceInfo.getServiceType().equals(mServiceType)) { 
       MLog.v(TAG, "Discovered: other serviceType: " + serviceInfo.getServiceType()); 
      } 
      // Make sure, that service name matches, and just resolve remote host 
      else if (serviceInfo.getServiceName().contains(mBaseServiceName)){ 
       MLog.d(TAG, "Discovered: correct serviceType: " + mBaseServiceName); 
       resolveService(serviceInfo); 
      } 
      else { 
       // Other service name, log anyway 
       MLog.d(TAG, "Discovered: service with different serviceName: " + serviceInfo.getServiceName() + ". Ignoring."); 
      } 
     } 

     @Override 
     public void onServiceLost(NsdServiceInfo service) { 
      MLog.e(TAG, "Service lost: " + service); 
      mNsdHandler.onRemotePeerLost(service); 
     } 

     @Override 
     public void onDiscoveryStopped(String serviceType) { 
      MLog.v(TAG, "Discovery stopped: " + serviceType); 
      mNsdHandler.onDiscoveryStopped(); 
     } 

     @Override 
     public void onStartDiscoveryFailed(String serviceType, int errorCode) { 
      MLog.e(TAG, "Discovery starting failed. Error code: " + errorCode); 
      synchronized (mDiscoveryLock) { 
       mDiscoveryListener = null; // just throw away the discovery listener, explicit stopping of the discovery should not be needed according to 
              // https://code.google.com/p/android/issues/detail?id=99510&q=nsd&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars 
      } 
     } 

     @Override 
     public void onStopDiscoveryFailed(String serviceType, int errorCode) { 
      MLog.e(TAG, "Discovery stopping failed. Error code: " + errorCode); 
      // try again 
      // mNsdManager.stopServiceDiscovery(this); // This should not be needed according to https://code.google.com/p/android/issues/detail?id=99510&q=nsd&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars 
     } 
    }; 

    private class MyRegistrationListener implements NsdManager.RegistrationListener { 

     @Override 
     public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) { 
      MLog.d(TAG, "Service registered. NsdServiceInfo: " + nsdServiceInfo); 

      boolean nameChanged = false; 

      // Update service name of this node (might change due to automatic conflict resolution!) 
      if(!mServiceName.equals(nsdServiceInfo.getServiceName())){ 
       mServiceName = nsdServiceInfo.getServiceName(); 

       nameChanged = true; 
       MLog.d(TAG, "Local service name updated to: " + mServiceName); 
      } 

      // Notify 
      if (mNsdHandler != null) { 
       mNsdHandler.onRegistrationSuccess(nsdServiceInfo); 

       if (nameChanged) { 
       mNsdHandler.onLocalServiceNameChanged(mServiceName); 
       } 
      } else { 
       MLog.w(TAG, "onServiceRegistered: NsdHandler is null."); 
      } 
     } 

     @Override 
     public void onRegistrationFailed(NsdServiceInfo arg0, int arg1) { 
      MLog.w(TAG, "Service registration failed with error code " + arg1 + "."); 

      if (mNsdHandler == null) { 
       MLog.w(TAG, "onRegistrationFailed: NsdHandler is null."); 
       return; 
      } 

      mNsdHandler.onRegistrationFailed(arg0, arg1); 
     } 

     @Override 
     public void onServiceUnregistered(NsdServiceInfo arg0) { 
      MLog.d(TAG, "Service unregistered."); 

      if (mNsdHandler == null) { 
       MLog.w(TAG, "onServiceUnRegistered: NsdHandler is null."); 
       return; 
      } 
     } 

     @Override 
     public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { 
      MLog.w(TAG, "Service unregistering failed."); 

      if (mNsdHandler == null) { 
       MLog.w(TAG, "onUnRegistrationFailed: NsdHandler is null."); 
       return; 
      } 
     } 

    }; 

    private class MyResolveListener implements NsdManager.ResolveListener { 

     private final String mServiceName; 

     public MyResolveListener(String serviceName) { 
      mServiceName = serviceName; 
     } 

     @Override 
     public void onResolveFailed(final NsdServiceInfo serviceInfo, int errorCode) { 
      // Release resource 
      mResolveSemaphore.release(); 

      MLog.e(TAG, "Resolve failed with error code: " + errorCode + ". Service: " + serviceInfo); 
      if((serviceInfo.getServiceName() != null) && (!serviceInfo.getServiceName().equals(mServiceName))) { 
       MLog.e(TAG, "Service name changed: " + mServiceName + " => " + serviceInfo.getServiceName()); 
      } 
     } 

     @Override 
     public void onServiceResolved(final NsdServiceInfo serviceInfo) { 
      // Release resource 
      mResolveSemaphore.release(); 

      MLog.v(TAG, "Resolve succeeded. Service: " + serviceInfo + ", Address: " + serviceInfo.getHost().getHostAddress() + ":" + serviceInfo.getPort()); 
      if((serviceInfo.getServiceName() != null) && (!serviceInfo.getServiceName().equals(mServiceName))) { 
       MLog.w(TAG, "Service name changed: " + mServiceName + " => " + serviceInfo.getServiceName()); 
      } 

      mNsdHandler.onNewRemotePeerResolved(serviceInfo); 
     } 
    }; 



    /** 
    * Interface for handlers that deal just with essential NSD events. 
    * @author Alexander Fischl ([email protected]) 
    */ 
    public interface NsdHandler { 

     /** 
     * Called, when the NSD manager registered the service successfully. 
     * @param nsdServiceInfo 
     */ 
     public void onRegistrationSuccess(final NsdServiceInfo nsdServiceInfo); 

     /** 
     * Called, when the NSD registration was unsuccessful. 
     */ 
     public void onRegistrationFailed(final NsdServiceInfo nsdServiceInfo, final int errorCode); 


     /** 
     * Called, when the NSD manager discovers a new peer. Services registered on the 
     * local machine DO NOT trigger this call! 
     * @param nsdServiceInfo 
     */ 
     public void onNewRemotePeerDiscovered(final NsdServiceInfo nsdServiceInfo); 

     /** 
     * Called, when the NSD manager resolves a new peer, yielding the connection data. 
     * Services registered on the local machine DO NOT trigger this call! 
     * @param nsdServiceInfo 
     */ 
     public void onNewRemotePeerResolved(final NsdServiceInfo nsdServiceInfo); 

     /** 
     * Called, when the NSD manager loses an already discovered peer. 
     * @param nsdServiceInfo 
     */ 
     public void onRemotePeerLost(final NsdServiceInfo nsdServiceInfo); 

     /** 
     * Called, when the local service name needs to be updated (e.g. due to 
     * conflict resolution when the local service is registered, and the chosen service 
     * name is already taken by another node in the network.) 
     * @param newLocalServiceName 
     */ 
     public void onLocalServiceNameChanged(String newLocalServiceName); 

     /** 
     * Called, when the service discovery has successfully started. 
     */ 
     public void onDiscoveryStarted(); 

     /** 
     * Called, when the service discovery was halted. 
     */ 
     public void onDiscoveryStopped(); 
    } 
} 

ध्यान दें, कि मैं यहां तक ​​कि एक सेमाफोर, समानांतर में कई सेवाओं को हल करने को रोकने के लिए 1 पर सेट किया जा सकता है कि के रूप में किसी और समानांतर संकल्प के साथ समस्याओं की सूचना दी कार्यान्वित किया। हालांकि, इसे 1 पर सेट करना काम नहीं करता है, क्योंकि कभी-कभी चल रहा संकल्प न तो सफल होता है और न ही विफल रहता है; जो सेमफोर को रिलीज़ नहीं किया जाता है और एनएसडीमेनगर थ्रेड को अगले समाधान अनुरोध पर स्थायी रूप से अटकने के लिए कारण बनता है।

किसी और इस तरह की समस्याओं का सामना कर रहा है? मैं अगर यह भी लोग हैं, जो सफलतापूर्वक NsdManager रोजगार कर रहे हैं टिप्पणी की खुशी होगी - कि कम से कम मैं एक समस्या मैं :)

मैं पहले से ही एनएसडी पर देने और अपने ही लागू करने पर विचार ठीक कर सकते हैं का सामना करना पड़ रहा है मतलब होगा प्रसारण/मल्टीकास्ट खोज तंत्र। यह सैद्धांतिक रूप से एक हवा हो सकता है, लेकिन मैं पढ़ा है Android पर कि बहुस्त्र्पीय क्योंकि कुछ इसे रोकने उपकरणों की भी एक PITA है ...

+0

मैं भी लगता है कि एनएसडी अस्थिर है। मैंने कुछ परीक्षण किए हैं और डिवाइस पंजीकरण के बावजूद यह हमेशा एक ही आईपी को हल करता है। और भी, मेरे पास 2 डिवाइस हैं लेकिन यह नेटवर्क पर 6-7 सेवाएं पंजीकृत करता है। –

+0

यहाँ एक ही, कुछ दिनों के समाधान और खोज शो कुछ भी नहीं के बाद। मुझे फिर से एनएसडी काम करने के लिए डिवाइस को पुनरारंभ करना होगा – Superbiji

उत्तर

1

फिर भी एंड्रॉयड एनएसडी के साथ कोई अंतर नहीं। मैं एंड्रॉइड के मार्शमलो संस्करण का उपयोग कर रहा था और एनएसडी वास्तव में अविश्वसनीय है। मैंने एनएसडी को आरएक्सडीएनएसएसडी (https://github.com/andriydruk/RxDNSSD) के साथ बदल दिया। कुछ लाइनर कोड अब तक सही काम करता है।

मैंने एनएसडी & आरएक्सडीएनएसएसडी का परीक्षण किया, एनएसडी सेवा खोजने में सक्षम था लेकिन आईपी पते को हल करने में सक्षम नहीं था, जबकि आरएक्सडीएनएसएसडी हर समय काम कर रहा था।

आशा है कि यह अन्य उपयोगकर्ताओं के लिए मदद मिलेगी।

संबंधित मुद्दे