Bushes
Bushes

Reputation: 1010

NSNetworkManager.ResolveListener messages Android

Can somebody explain the error messages that can be passed into the callbacks i.e.

public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode)

I've seen error code 3 before but have no idea what it means. The documentation seems flakey at best...

Cheers,

Upvotes: 3

Views: 3443

Answers (5)

slott
slott

Reputation: 3335

I found that reusing the same listener with a semaphore gave the best result.

if (semaphore.tryAcquire()) {
    mNsdManager.resolveService(service, resolveListener);
}

Using tryAcquire as we do not wan't to block onServiceFound which will lock it completely. With this approach we eventually get all services on the network to show up.

Upvotes: 0

travisa
travisa

Reputation: 1077

I worked around this by calling resolveService again. It may fail a couple of times in a row, but eventually resolves.

        @Override
        public void onServiceFound(NsdServiceInfo serviceInfo) {
            Log.d(TAG, "Service found: "+ serviceInfo);
            if (!serviceInfo.getServiceType().equals(SERVICE_TYPE)){
                Log.d(TAG, "Unknown service type: " + serviceInfo.getServiceType());
            } else if (serviceInfo.getServiceName().equals(mServiceName)){
                Log.d(TAG, "Same machine");
            } else {
                startResolveService(serviceInfo);
            }
        }

Rather than call resolveService from within onServiceFound, I call a separate declaration of it:

        private void startResolveService(NsdServiceInfo serviceInfo){
            NsdManager.ResolveListener newResolveListener = new NsdManager.ResolveListener() {
                @Override
                public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                    Log.e(TAG, "Resolve Failed: " + serviceInfo + "\tError Code: " + errorCode);
                    switch (errorCode) {
                        case NsdManager.FAILURE_ALREADY_ACTIVE:
                            Log.e(TAG, "FAILURE_ALREADY_ACTIVE");
                            // Just try again...
                            startResolveService(serviceInfo);
                            break;
                        case NsdManager.FAILURE_INTERNAL_ERROR:
                            Log.e(TAG, "FAILURE_INTERNAL_ERROR");
                            break;
                        case NsdManager.FAILURE_MAX_LIMIT:
                            Log.e(TAG, "FAILURE_MAX_LIMIT");
                            break;
                    }
                 }

                @Override
                public void onServiceResolved(NsdServiceInfo serviceInfo) {
                    Log.i(TAG, "Service Resolved: " + serviceInfo);
                    mLocatedServices.add(serviceInfo);
                    reportNewService();
                }
            };
            mNsdManager.resolveService(serviceInfo, newResolveListener);
        }

When multiple services are discovered nearly-instantaneously, the first one gets resolved, then you get FAILURE_ALREADY_ACTIVE once or twice more, then the next service gets resolved, and so on.

Upvotes: 13

user3804576
user3804576

Reputation: 1

I met this problem two days....and i solve it...

first time i do resolveService(service, mResolveListener);

no callback

and i do again same service, resolveService(service, mResolveListener);

the callback is error code 3

At least I found ,because my server name is "III...."

I take out double quotes and it's work

hope it's can help you.

Upvotes: 0

aaronvargas
aaronvargas

Reputation: 14182

I was a bit confused by this also...

Here's what's happening. When you are discovering services, you will often get the exact same service a few times in the same millisecond.

if you log the output from NsdManager.DiscoveryListener.onServiceFound(NsdServiceInfo service) you'll see this.

Now, you probably resolve the service using mNsdManager.resolveService(service, mResolveListener). Only the first attempt is going to start resolving, the others will give FAILURE_ALREADY_ACTIVE. (At least until the first is completed)

Upvotes: 1

chebur
chebur

Reputation: 56

Had the same question and got the answer from NsdManager sources:

/**
 * Failures are passed with {@link RegistrationListener#onRegistrationFailed},
 * {@link RegistrationListener#onUnregistrationFailed},
 * {@link DiscoveryListener#onStartDiscoveryFailed},
 * {@link DiscoveryListener#onStopDiscoveryFailed} or {@link ResolveListener#onResolveFailed}.
 *
 * Indicates that the operation failed due to an internal error.
 */
public static final int FAILURE_INTERNAL_ERROR               = 0;

/**
 * Indicates that the operation failed because it is already active.
 */
public static final int FAILURE_ALREADY_ACTIVE              = 3;

/**
 * Indicates that the operation failed because the maximum outstanding
 * requests from the applications have reached.
 */
public static final int FAILURE_MAX_LIMIT                   = 4;

edited:

Actually it is mentioned in developer documentation: http://developer.android.com/reference/android/net/nsd/NsdManager.html

Upvotes: 2

Related Questions