नेटवर्क सेवा खोजने की सुविधा का इस्तेमाल करें

नेटवर्क सर्विस डिस्कवरी (एनएसडी), आपके ऐप्लिकेशन को उन सेवाओं का ऐक्सेस देता है जो लोकल नेटवर्क पर उपलब्ध होने चाहिए. एनएसडी की सुविधा वाले डिवाइसों में प्रिंटर, वेबकैम, एचटीटीपीएस सर्वर, और अन्य मोबाइल डिवाइस.

एनएसडी ने डीएनएस-आधारित सर्विस डिस्कवरी (डीएनएस-एसडी) तकनीक को लागू किया है, जो आपके ऐप्लिकेशन को सेवा का प्रकार और नाम तय करके सेवाओं का अनुरोध करने की अनुमति देता है किसी ऐसे डिवाइस इंस्टेंस का प्रतिशत जो आपकी पसंद की सेवा देता हो. DNS-SD यह है Android और अन्य मोबाइल प्लैटफ़ॉर्म, दोनों पर काम करता है.

अपने ऐप्लिकेशन में एनएसडी जोड़ने से, आपके उपयोगकर्ता ऐसा लोकल नेटवर्क जो आपके ऐप्लिकेशन के लिए अनुरोध की गई सेवाओं के साथ काम करता है. यह ऐसे लोगों के लिए फ़ायदेमंद है पीयर-टू-पीयर ऐप्लिकेशन की सुविधा. जैसे- फ़ाइल शेयर करना या एक से ज़्यादा खिलाड़ी वाले ऐप्लिकेशन गेमिंग. Android के NSD एपीआई, इन्हें लागू करने की प्रोसेस को आसान बनाते हैं सुविधाएं उपलब्ध कराना.

यह लेख आपको एक ऐसा ऐप्लिकेशन बनाने का तरीका बताता है, जो लोकल नेटवर्क से आपके नाम और कनेक्शन की जानकारी और जानकारी के लिए स्कैन करें अन्य ऐप्लिकेशन से कनेक्ट कर लेता है. आखिर में, इस लेसन में बताया गया है कि का इस्तेमाल करें.

अपनी सेवा को नेटवर्क पर रजिस्टर करें

ध्यान दें: यह चरण ज़रूरी नहीं है. अगर आपने आपको स्थानीय नेटवर्क पर अपने ऐप्लिकेशन की सेवाओं के ब्रॉडकास्ट की कोई चिंता नहीं है, आप इसे छोड़कर आगे की ओर बढ़ सकते हैं अगला सेक्शन, नेटवर्क पर सेवाएं खोजें पर जाएं.

अपनी सेवा को लोकल नेटवर्क पर रजिस्टर करने के लिए, पहले NsdServiceInfo ऑब्जेक्ट बनाएं. यह ऑब्जेक्ट जानकारी देता है नेटवर्क के अन्य डिवाइस, उस समय इस्तेमाल करते हैं जब वे यह तय कर रहे होते हैं कि कनेक्ट करना है या नहीं सेवा.

Kotlin

fun registerService(port: Int) {
    // Create the NsdServiceInfo object, and populate it.
    val serviceInfo = NsdServiceInfo().apply {
        // The name is subject to change based on conflicts
        // with other services advertised on the same network.
        serviceName = "NsdChat"
        serviceType = "_nsdchat._tcp"
        setPort(port)
        ...
    }
}

Java

public void registerService(int port) {
    // Create the NsdServiceInfo object, and populate it.
    NsdServiceInfo serviceInfo = new NsdServiceInfo();

    // The name is subject to change based on conflicts
    // with other services advertised on the same network.
    serviceInfo.setServiceName("NsdChat");
    serviceInfo.setServiceType("_nsdchat._tcp");
    serviceInfo.setPort(port);
    ...
}

यह कोड स्निपेट, सेवा का नाम "NsdChat" पर सेट करता है. सेवा का नाम इंस्टेंस का नाम है: यह नेटवर्क पर मौजूद अन्य डिवाइसों को दिखने वाला नाम है. यह नाम, नेटवर्क पर मौजूद ऐसे किसी भी डिवाइस पर दिखेगा जो एनएसडी की मदद से खोज रहा है स्थानीय सेवाओं से कनेक्ट करने के लिए किया जा सकता है. ध्यान रखें कि Google Play पर एक ही नेटवर्क से कनेक्ट किया जाता है और Android समस्या के समाधान को अपने-आप मैनेज करता है. अगर आपने नेटवर्क से जुड़े दो डिवाइस में NsdChat ऐप्लिकेशन इंस्टॉल है, जिनमें से एक तो सेवा का नाम अपने-आप बदलकर "NsdChat" हो जाता है (1)".

दूसरा पैरामीटर, सेवा का टाइप सेट करता है. इससे पता चलता है कि कौनसा प्रोटोकॉल और ट्रांसपोर्ट लेयर होती है जिसका इस्तेमाल ऐप्लिकेशन करता है. इसका सिंटैक्स यह है "_<protocol>._<ट्रांसपोर्टलेयर>". इस कोड स्निपेट है, तो सेवा टीसीपी पर चल रहे एचटीटीपी प्रोटोकॉल का इस्तेमाल करती है. ऐप्लिकेशन (उदाहरण के लिए, नेटवर्क प्रिंटर) जो प्रिंटर सेवा देने वाली कंपनी के साथ सेवा टाइप को "_ipp._tcp" पर सेट करें.

ध्यान दें: अंतरराष्ट्रीय असाइन किए गए नंबर अथॉरिटी (IANA) एक ही जगह से मैनेज की जाती है, उन सेवाओं की आधिकारिक सूची जिनका इस्तेमाल NSD और Bonjour जैसे सेवा डिस्कवरी प्रोटोकॉल में किया जाता है. आप यहां से सूची डाउनलोड कर सकते हैं: सेवा के नाम और पोर्ट नंबर की आईएएनए सूची. अगर आप नई सेवा का इस्तेमाल करना चाहते हैं, तो आपको इसे भरकर रिज़र्व करना होगा IANA पोर्ट और सेवा रजिस्ट्रेशन फ़ॉर्म भरें.

अपनी सेवा के लिए पोर्ट सेट करते समय, इसे इस तरह हार्डकोड करने से बचें अन्य ऐप्लिकेशन से विरोध होता है. उदाहरण के लिए, अगर कि आपका ऐप्लिकेशन हमेशा पोर्ट 1337 का इस्तेमाल करता है, जिससे इसे उसी पोर्ट का उपयोग करने वाले अन् य इंस् टॉल किए गए ऐप्लिकेशन. इसके बजाय, डिवाइस के अगला उपलब्ध पोर्ट. क्योंकि यह जानकारी दूसरे ऐप्लिकेशन को सेवा प्रसारण के लिए, आपके एप्लिकेशन द्वारा उपयोग किए जाने वाले पोर्ट की कोई आवश्यकता नहीं है जिसे कंपाइल-टाइम पर अन्य ऐप्लिकेशन की मदद से जाना जाता है. इसके बजाय, ऐप्लिकेशन यह पा सकते हैं आपके नेटवर्क से कनेक्ट करने से ठीक पहले, सेवा.

अगर आप सॉकेट के साथ काम कर रहे हैं, तो यहां बताया गया है कि किसी उपलब्ध पोर्ट को बस 0 पर सेट करके देखा जा सकता है.

Kotlin

fun initializeServerSocket() {
    // Initialize a server socket on the next available port.
    serverSocket = ServerSocket(0).also { socket ->
        // Store the chosen port.
        mLocalPort = socket.localPort
        ...
    }
}

Java

public void initializeServerSocket() {
    // Initialize a server socket on the next available port.
    serverSocket = new ServerSocket(0);

    // Store the chosen port.
    localPort = serverSocket.getLocalPort();
    ...
}

NsdServiceInfo ऑब्जेक्ट तय करने के बाद, अब आपको RegistrationListener इंटरफ़ेस लागू करना होगा. यह इंटरफ़ेस में Android द्वारा उपयोग की जाने वाली कॉलबैक शामिल होती हैं, जो सेवा पंजीकरण और अ-रजिस्ट्रेशन की सफलता या विफलता.

Kotlin

private val registrationListener = object : NsdManager.RegistrationListener {

    override fun onServiceRegistered(NsdServiceInfo: NsdServiceInfo) {
        // Save the service name. Android may have changed it in order to
        // resolve a conflict, so update the name you initially requested
        // with the name Android actually used.
        mServiceName = NsdServiceInfo.serviceName
    }

    override fun onRegistrationFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
        // Registration failed! Put debugging code here to determine why.
    }

    override fun onServiceUnregistered(arg0: NsdServiceInfo) {
        // Service has been unregistered. This only happens when you call
        // NsdManager.unregisterService() and pass in this listener.
    }

    override fun onUnregistrationFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
        // Unregistration failed. Put debugging code here to determine why.
    }
}

Java

public void initializeRegistrationListener() {
    registrationListener = new NsdManager.RegistrationListener() {

        @Override
        public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
            // Save the service name. Android may have changed it in order to
            // resolve a conflict, so update the name you initially requested
            // with the name Android actually used.
            serviceName = NsdServiceInfo.getServiceName();
        }

        @Override
        public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
            // Registration failed! Put debugging code here to determine why.
        }

        @Override
        public void onServiceUnregistered(NsdServiceInfo arg0) {
            // Service has been unregistered. This only happens when you call
            // NsdManager.unregisterService() and pass in this listener.
        }

        @Override
        public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
            // Unregistration failed. Put debugging code here to determine why.
        }
    };
}

अब आपके पास अपनी सेवा रजिस्टर करने के लिए सभी चीज़ें हैं. तरीके को कॉल करें registerService().

ध्यान दें कि यह तरीका एसिंक्रोनस है. इसलिए, ऐसा कोई भी कोड जिसे चलाने की ज़रूरत हो सेवा के रजिस्टर होने के बाद, onServiceRegistered() तरीके का इस्तेमाल करना चाहिए.

Kotlin

fun registerService(port: Int) {
    // Create the NsdServiceInfo object, and populate it.
    val serviceInfo = NsdServiceInfo().apply {
        // The name is subject to change based on conflicts
        // with other services advertised on the same network.
        serviceName = "NsdChat"
        serviceType = "_nsdchat._tcp"
        setPort(port)
    }

    nsdManager = (getSystemService(Context.NSD_SERVICE) as NsdManager).apply {
        registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener)
    }
}

Java

public void registerService(int port) {
    NsdServiceInfo serviceInfo = new NsdServiceInfo();
    serviceInfo.setServiceName("NsdChat");
    serviceInfo.setServiceType("_http._tcp.");
    serviceInfo.setPort(port);

    nsdManager = Context.getSystemService(Context.NSD_SERVICE);

    nsdManager.registerService(
            serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener);
}

नेटवर्क पर सेवाएं खोजें

यह नेटवर्क, खतरनाक नेटवर्क प्रिंटर से लेकर विनम्र नेटवर्क वेबकैम, आस-पास मौजूद टिक-टैक-टो की खतरनाक लड़ाइयों तक खिलाड़ी. अपने ऐप्लिकेशन को यह अहम जानकारी देने का सबसे अच्छा तरीका है कि सुविधा है, सेवा खोजना. आपके ऐप्लिकेशन को सेवा पर ध्यान देने की ज़रूरत है नेटवर्क पर ब्रॉडकास्ट करता है कि क्या सेवाएं उपलब्ध हैं. साथ ही, मैसेज को फ़िल्टर किया जा सकता है ऐसी कोई भी चीज़ जिसके साथ ऐप्लिकेशन काम नहीं कर सकता.

सेवा रजिस्ट्रेशन की तरह, सेवा खोजने के दो चरण हैं: काम के कॉलबैक के साथ डिस्कवरी लिसनर सेट अप करना और सिंगल एसिंक्रोनस बनाना discoverServices() पर एपीआई कॉल.

सबसे पहले, एक ऐसी अनाम क्लास इंस्टैंशिएट करें, जो NsdManager.DiscoveryListener को लागू करती है. नीचे दिया गया स्निपेट एक आसान उदाहरण:

Kotlin

// Instantiate a new DiscoveryListener
private val discoveryListener = object : NsdManager.DiscoveryListener {

    // Called as soon as service discovery begins.
    override fun onDiscoveryStarted(regType: String) {
        Log.d(TAG, "Service discovery started")
    }

    override fun onServiceFound(service: NsdServiceInfo) {
        // A service was found! Do something with it.
        Log.d(TAG, "Service discovery success$service")
        when {
            service.serviceType != SERVICE_TYPE -> // Service type is the string containing the protocol and
                // transport layer for this service.
                Log.d(TAG, "Unknown Service Type: ${service.serviceType}")
            service.serviceName == mServiceName -> // The name of the service tells the user what they'd be
                // connecting to. It could be "Bob's Chat App".
                Log.d(TAG, "Same machine: $mServiceName")
            service.serviceName.contains("NsdChat") -> nsdManager.resolveService(service, resolveListener)
        }
    }

    override fun onServiceLost(service: NsdServiceInfo) {
        // When the network service is no longer available.
        // Internal bookkeeping code goes here.
        Log.e(TAG, "service lost: $service")
    }

    override fun onDiscoveryStopped(serviceType: String) {
        Log.i(TAG, "Discovery stopped: $serviceType")
    }

    override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
        Log.e(TAG, "Discovery failed: Error code:$errorCode")
        nsdManager.stopServiceDiscovery(this)
    }

    override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
        Log.e(TAG, "Discovery failed: Error code:$errorCode")
        nsdManager.stopServiceDiscovery(this)
    }
}

Java

public void initializeDiscoveryListener() {

    // Instantiate a new DiscoveryListener
    discoveryListener = new NsdManager.DiscoveryListener() {

        // Called as soon as service discovery begins.
        @Override
        public void onDiscoveryStarted(String regType) {
            Log.d(TAG, "Service discovery started");
        }

        @Override
        public void onServiceFound(NsdServiceInfo service) {
            // A service was found! Do something with it.
            Log.d(TAG, "Service discovery success" + service);
            if (!service.getServiceType().equals(SERVICE_TYPE)) {
                // Service type is the string containing the protocol and
                // transport layer for this service.
                Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
            } else if (service.getServiceName().equals(serviceName)) {
                // The name of the service tells the user what they'd be
                // connecting to. It could be "Bob's Chat App".
                Log.d(TAG, "Same machine: " + serviceName);
            } else if (service.getServiceName().contains("NsdChat")){
                nsdManager.resolveService(service, resolveListener);
            }
        }

        @Override
        public void onServiceLost(NsdServiceInfo service) {
            // When the network service is no longer available.
            // Internal bookkeeping code goes here.
            Log.e(TAG, "service lost: " + service);
        }

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

        @Override
        public void onStartDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            nsdManager.stopServiceDiscovery(this);
        }

        @Override
        public void onStopDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            nsdManager.stopServiceDiscovery(this);
        }
    };
}

ऐप्लिकेशन खोजे जाने पर, NSD API इस इंटरफ़ेस में बताए गए तरीकों का इस्तेमाल करके, आपके ऐप्लिकेशन की जानकारी देता है से शुरू हो जाता है, जब वह विफल हो जाता है, और जब सेवाएँ मिलती हैं और खो जाती हैं (खोने का मतलब है " अब उपलब्ध नहीं है"). ध्यान दें कि यह स्निपेट कई तरह की जांच करता है खोज के नतीजे पाने के लिए.

  1. खोजी गई सेवा के सेवा नाम की तुलना सेवा से की जाती है स्थानीय सेवा का नाम, ताकि यह पता लगाया जा सके कि डिवाइस ने अभी-अभी खुद से काम किया है या नहीं ब्रॉडकास्ट करना चाहिए (जो मान्य है).
  2. सेवा के टाइप की जांच की जाती है, ताकि यह पुष्टि की जा सके कि यह उसी तरह की सेवा है ऐप्स से कनेक्ट हो सकता है.
  3. सेवा के नाम की जांच की गई है, ताकि सही के साथ कनेक्शन की पुष्टि की जा सके का इस्तेमाल करें.

सेवा के नाम की जांच करना हमेशा ज़रूरी नहीं होता. साथ ही, यह सिर्फ़ तभी काम का होता है, जब किसी ख़ास ऐप्लिकेशन से कनेक्ट करना चाहते हैं. उदाहरण के लिए, ऐप्लिकेशन को सिर्फ़ अन्य डिवाइस पर चलने वाले इंस्टेंस से कनेक्ट करना हो. हालांकि, अगर ऐप्लिकेशन किसी नेटवर्क प्रिंटर से कनेक्ट करना चाहता है, तो बस यह देखना काफ़ी होता है कि सेवा टाइप "_ipp._tcp" है.

लिसनर सेट करने के बाद, discoverServices() को कॉल करें और सर्विस टाइप बताएं ऐप्लिकेशन को, इन्हें खोजना चाहिए. साथ ही, इस्तेमाल के लिए डिस्कवरी प्रोटोकॉल और लिसनर जिसे आपने अभी-अभी बनाया है.

Kotlin

nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener)

Java

nsdManager.discoverServices(
        SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener);

नेटवर्क पर मौजूद सेवाओं से कनेक्ट करें

जब आपका ऐप्लिकेशन, नेटवर्क से कनेक्ट करने के लिए कोई सेवा ढूंढता है, तो वह को पहले इसका उपयोग करके उस सेवा की कनेक्शन जानकारी का पता लगाना होगा resolveService() तरीका. इसे लागू करने के लिए NsdManager.ResolveListener लागू करें विधि का इस्तेमाल करें और इसका इस्तेमाल करके NsdServiceInfo को पाएं कनेक्शन की जानकारी.

Kotlin

private val resolveListener = object : NsdManager.ResolveListener {

    override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
        // Called when the resolve fails. Use the error code to debug.
        Log.e(TAG, "Resolve failed: $errorCode")
    }

    override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
        Log.e(TAG, "Resolve Succeeded. $serviceInfo")

        if (serviceInfo.serviceName == mServiceName) {
            Log.d(TAG, "Same IP.")
            return
        }
        mService = serviceInfo
        val port: Int = serviceInfo.port
        val host: InetAddress = serviceInfo.host
    }
}

Java

public void initializeResolveListener() {
    resolveListener = new NsdManager.ResolveListener() {

        @Override
        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
            // Called when the resolve fails. Use the error code to debug.
            Log.e(TAG, "Resolve failed: " + errorCode);
        }

        @Override
        public void onServiceResolved(NsdServiceInfo serviceInfo) {
            Log.e(TAG, "Resolve Succeeded. " + serviceInfo);

            if (serviceInfo.getServiceName().equals(serviceName)) {
                Log.d(TAG, "Same IP.");
                return;
            }
            mService = serviceInfo;
            int port = mService.getPort();
            InetAddress host = mService.getHost();
        }
    };
}

सेवा का समाधान होने के बाद, आपके ऐप्लिकेशन को पूरी जानकारी सेवा की जानकारी, जिसमें आईपी पता और पोर्ट नंबर शामिल है. यह सब कुछ है आपको सेवा से अपना खुद का नेटवर्क कनेक्शन बनाना होगा.

ऐप्लिकेशन बंद होने पर अपनी सेवा का रजिस्ट्रेशन रद्द करें

एनएसडी को चालू और बंद करना ज़रूरी है जो ऐप्लिकेशन के काम करने के दौरान ज़रूरत के मुताबिक हो लाइफ़साइकल. ऐप्लिकेशन के बंद होने पर उसका रजिस्ट्रेशन रद्द करने से, दूसरे ऐप्लिकेशन जो यह सोचते हैं कि वह अब भी सक्रिय है और उससे कनेक्ट करने का प्रयास कर रहा है इसे. इसके अलावा, सेवा खोजना एक महंगा संचालन है और इसे बंद किया जाना चाहिए जब माता-पिता की गतिविधि को रोका जाता है और गतिविधि को फिर से शुरू कर दिया गया है. अपनी मुख्य ऐक्टिविटी के लाइफ़साइकल के तरीकों को बदलें और कोड डालें सेवा प्रसारण और खोज को शुरू और बंद करने के लिए.

Kotlin

    // In your application's Activity

    override fun onPause() {
        nsdHelper?.tearDown()
        super.onPause()
    }

    override fun onResume() {
        super.onResume()
        nsdHelper?.apply {
            registerService(connection.localPort)
            discoverServices()
        }
    }

    override fun onDestroy() {
        nsdHelper?.tearDown()
        connection.tearDown()
        super.onDestroy()
    }

    // NsdHelper's tearDown method
    fun tearDown() {
        nsdManager.apply {
            unregisterService(registrationListener)
            stopServiceDiscovery(discoveryListener)
        }
    }

Java

    // In your application's Activity

    @Override
    protected void onPause() {
        if (nsdHelper != null) {
            nsdHelper.tearDown();
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (nsdHelper != null) {
            nsdHelper.registerService(connection.getLocalPort());
            nsdHelper.discoverServices();
        }
    }

    @Override
    protected void onDestroy() {
        nsdHelper.tearDown();
        connection.tearDown();
        super.onDestroy();
    }

    // NsdHelper's tearDown method
    public void tearDown() {
        nsdManager.unregisterService(registrationListener);
        nsdManager.stopServiceDiscovery(discoveryListener);
    }