Android NSD: почему тип сервиса не совпадает - PullRequest
0 голосов
/ 28 ноября 2018

Я создал приложение для проверки обнаружения сетевых служб (NSD) на Android.

Сбойный сценарий

Два устройства, на которых запущено приложение.Я нажимаю register на первом устройстве, и после того, как я вижу тост, подтверждающий регистрацию, я нажимаю обнаружить на другом устройстве.

Служба обнаружена вторым устройствомно это тип неизвестен .В результате отладки я обнаружил, что неизвестный тип службы -

_mynsd._tcp.

, но когда служба зарегистрирована, ее тип устанавливается на

_mynsd._tcp // (without the dot at the end)

. Не думаю, что я сделал что-то, что изменится.тип услуги.Вот упражнение:

public class MainActivity extends AppCompatActivity {
    private static final String SERVICE_TYPE = "_mynsd._tcp";

    private ServerSocket serverSocket;
    private int localPort;

    private NsdManager.RegistrationListener registrationListener;
    private NsdManager.DiscoveryListener discoveryListener;
    private NsdManager nsdManager;
    private String serviceName;
    private NsdServiceInfo service;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initializeRegistrationListener();
        initializeServerSocket();
        nsdManager = (NsdManager) getSystemService(NSD_SERVICE);
    }

    public void onRegisterClicked(View view) {
        registerService(localPort);
    }

    public void onDiscoverClicked(View view) {
        if (discoveryListener == null)
            initializeDiscoveryListener();
        nsdManager.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener);
    }

    public void onConnectClicked(View view) {

    }

    @Override
    protected void onPause() {
        super.onPause();
        if (nsdManager != null)
            nsdManager.unregisterService(registrationListener);
    }

    public void registerService(int port) {
        NsdServiceInfo serviceInfo = new NsdServiceInfo();
        serviceInfo.setServiceName("MyNsd");
        serviceInfo.setServiceType(SERVICE_TYPE);
        serviceInfo.setPort(port);

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

    public void initializeServerSocket() {
        try {
            serverSocket = new ServerSocket(0);
            localPort = serverSocket.getLocalPort();
        } catch (IOException e) {
            Toast.makeText(this, "Error with server socket", Toast.LENGTH_SHORT).show();
        }
    }

    public void initializeDiscoveryListener() {
        discoveryListener = new NsdManager.DiscoveryListener() {
            @Override
            public void onStartDiscoveryFailed(String s, int i) {
                Toast.makeText(MainActivity.this, "Start discovery failed", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStopDiscoveryFailed(String s, int i) {
                Toast.makeText(MainActivity.this, "Stop discovery failed ", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDiscoveryStarted(String s) {
                Toast.makeText(MainActivity.this, "Started discovery", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onDiscoveryStopped(String s) {
                Toast.makeText(MainActivity.this, "Stopped discovery", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
                Toast.makeText(MainActivity.this, nsdServiceInfo.getServiceName() + " service found", Toast.LENGTH_SHORT).show();

                if (!nsdServiceInfo.getServiceType().equals(SERVICE_TYPE)) {
                    Toast.makeText(MainActivity.this, "Unknown service type "+nsdServiceInfo.getServiceType(), Toast.LENGTH_SHORT).show();
                } else if (nsdServiceInfo.getServiceName().equals(serviceName)) {
                    // The one who registered the service is the one which actually holds the
                    // service name and its not null, so if we are here its the same machine
                    // who registered the service in the first place.
                    Toast.makeText(MainActivity.this, "Same machine: " + serviceName, Toast.LENGTH_SHORT).show();
                } else if (nsdServiceInfo.getServiceName().contains("MyNsd")) {
                    nsdManager.resolveService(nsdServiceInfo, new NsdManager.ResolveListener() {
                        @Override
                        public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
                            Toast.makeText(MainActivity.this, "Could not resolve " + nsdServiceInfo.getServiceName(), Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
                            Toast.makeText(MainActivity.this, "Resolved  " + nsdServiceInfo.getServiceName(), Toast.LENGTH_SHORT).show();
                            if (nsdServiceInfo.getServiceName().equals(serviceName)){
                                Toast.makeText(MainActivity.this, "Same IP", Toast.LENGTH_SHORT).show();
                                return;
                            }

                            service = nsdServiceInfo;
                            int port = service.getPort();
                            InetAddress host = service.getHost();
                        }
                    });
                }
            }

            @Override
            public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
                Toast.makeText(MainActivity.this, nsdServiceInfo.getServiceName() + " service lost", Toast.LENGTH_SHORT).show();
            }
        };
    }

    public void initializeRegistrationListener() {
        registrationListener = new NsdManager.RegistrationListener() {
            @Override
            public void onRegistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
                Toast.makeText(MainActivity.this, "Registration failed!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onUnregistrationFailed(NsdServiceInfo nsdServiceInfo, int i) {
                Toast.makeText(MainActivity.this, "Unregistration failed", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onServiceRegistered(NsdServiceInfo nsdServiceInfo) {
                Toast.makeText(MainActivity.this, "Service registered", Toast.LENGTH_SHORT).show();
                serviceName = nsdServiceInfo.getServiceName();
            }

            @Override
            public void onServiceUnregistered(NsdServiceInfo nsdServiceInfo) {
                Toast.makeText(MainActivity.this, "Service unregistered", Toast.LENGTH_SHORT).show();
            }
        };
    }
}

, а вот макет:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:onClick="onRegisterClicked"
        android:text="Register"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/discover"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:onClick="onDiscoverClicked"
        android:text="Discover"
        app:layout_constraintStart_toEndOf="@+id/register"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/connect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginTop="8dp"
        android:onClick="onConnectClicked"
        android:text="connect"
        app:layout_constraintStart_toEndOf="@+id/discover"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

1 Ответ

0 голосов
/ 28 ноября 2018

Вы должны зарегистрировать его в DNS в виде SRV записи, только тогда она станет известна.возможно, если вы установите одно устройство в качестве сервера имен для другого устройства, эта регистрация на localhost может сработать.объяснил это однажды здесь ;это облачный DNS, но для ответа на реальный вопрос достаточно localdomain.

любого локального сервера имен. Это абсолютное доменное имя (с завершающим .) и относительное доменное имя.

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