How to advertise server IP on the network?

Asked

Viewed 2,109 times

11

I am developing an application composed of a server NodeJS which shall provide data in JSON for customers, in case an application for Android, all running on internal network.

I have already managed to do the entire communication process and everything works as expected, but I am setting the IP and server port in a fixed way both on the server and on the client (for example 192.168.1.15:3300).

I wonder if there is a way to announce the server IP on the network since it may change at some point, as for example in online games, where a list with connected servers is shown.

I have thought about scanning the port of my server across the network, but this process can become slow, even more that the client may not have much processing power.

Is there any faster or better way to "announce" the server IP on the network so clients can connect?

  • Look if I understood what you want is for customers to know which IP is distributing JSON, wouldn’t it be better to fix it? I don’t know if I understand what you need

  • In the current example it is fixed as commented, but the server may change the IP for some reason and no longer get the IP fixed in the clients. I need the server to somehow count what IP it is running on. But Thanks for the comment anyway.

  • I get it, if the IP is only local I believe the tracking is not slow, if you use something like try { Socket socket = new Socket(); socket.connect(new InetSocketAddress(ip, 3300), timeout); socket.close(); return true; } catch (Exception ex) { return false; } and a loop

  • 3

    Can’t use DNS? Simplify.

  • 1

    It is not possible to loop over the IP’s, imagine something like 200 connected clients, now imagine making a loop over the 200 IP’s (if the server is the last of course) made by a Smartphone and this without considering the Timeout. I did a test with 30 Ips and it took more than 1 minute to find the server. Maybe there is a better algorithm. I may have done something wrong.

2 answers

9


Peter, in fact searching the network for the service/device is unviable, especially if you can’t use something like nmap (with some Binding for the nodejs) on the client device.

My suggestion is that you do not implement anything at hand and use protocols already known for this purpose, for example the SSDP.

The simple service discovery protocol (SSDP) is a network protocol of the set of internet protocols, for dissemination and discovery of network services and presence of information. It fulfills this goal without assistance from server-based configuration mechanisms, such as the DHCP or the DNS, and no static settings. SSDP is the basis of the discovery protocol of Universal Plug and Play (Upnp).

SSDP is a protocol based on HTTPU which is an extension of HTTP 1.1 using UDP as the transport layer.

The server announces the service available by doing multicast IP to the port 1900. The multicast address range is 239.0.0.0 - 239.255.255.255. The verb HTTP is used NOTIFY to announce or notify the deactivation of a service.

For a client to discover services available in a network is used the verb M-SEARCH and replies to these requests are returned in unicast (one-on-one communication) to the same address and door that originated it.

Clarifying

In the architecture of your application both clients (smartphones) and the server will listen and send messages. Initially, when no one knows no one there can be two situations:

1- The server just entered the network, suppose your server just got back from a reboot - it then multicast for everyone on the network, on port 1900 with UDP, sending a verb NOTIFY, with all necessary information of your network location (ip and port). Customers (smartphones) who are already listening at port 1900 receive the request and from there use this information as they wish.

2- A new client has just entered the network and wants to discover the server. He then sends a multicast to port 1900, with the verb M-SEARCH. The server receives this request and returns the request to the same originating address and port, the client receives the return and does what he wants with the information.

Why use all this?

So you don’t have to create your own service discovery protocol and don’t waste time developing libraries that already deal with it. Node already has modules that abstract this type of problem and I bet there are libraries for smartphones that also do it.

How to implement all this?

1- You implement everything at hand, or
2- You can use the module super-ssdp which is super simple and has a tiny API:

var ssdp = require('super-ssdp'),
    ip = require('ip'),
    porta = (Math.random() * 10000).toFixed(0), // Porta fake. Coloque aqui a porta do seu serviço principal
    peer = ssdp.createPeer({
        name: 'suaAplicação',
        url: 'http://' + ip.address() + ':' + porta
    });

peer.start();

peer.on('found', function(endereco) {
    console.log('Serviço encontrado!', endereco);
});

To test the above code you need to do the following; npm install super-ssdp ip and then node app.js (or the file name you prefer). Now open another terminal (to simulate another device) and run the last command again. Preferably test on another computer connected to the network.

More Tests

Let’s test that any client, smartphone in your case, is able to find the server.

In a terminal tab run the above code, in another turn this

var dgram = require('dgram'),
    ip = require('ip');

//0- Este é o nosso request HTTPU
var msearch = new Buffer(
    'M-SEARCH * HTTP/1.1\r\n' +
    'HOST:239.255.255.250:1900\r\n' +
    'MAN:\"ssdp:discover\"\r\n' +
    'ST:ssdp:all\r\n' +
    'MX:3\r\n' +
    '\r\n'
);

//1- Criamos um socket para enviar o M-SEARCH e escutar a resposta
var client = dgram.createSocket('udp4');

//2- Este socket escuta numa porta que o proprio SO vai designar,
//   e em todos os endereços, não apenas localhost
client.bind(function() {
    client.on('message', function(msg, rinfo) {
        //3- Aqui trataremos a reposta
        if(rinfo.address !== ip.address()) {
            //4- Só estamos interessados em mensagens vindas do localhost.
            //   Se você não colocar este `if` você vai receber varias mensagens
            //   do seu roteador, por exemplo!
            return;
        }

        //5- Imprimimos a resposta que contem o IP e porta do servidor.
        //   O ideal aqui seria fazer um parse da resposta.
        console.log(msg.toString());
    });

    //6- Enviamos o M-SEARCH para todo mundo, repare a porta e o endereço multicast
    client.send(msearch, 0, msearch.length, 1900, '239.255.255.250', function() {
        console.log('M-SEARCH enviado...');
    });
});

In the code above we implemented in hand the code of an SSDP client, which is precisely what the library for Android or iOS should do for you.

We could even implement another test in which the server 2 sends a NOTIFY for the service1 but the library super-ssdp has not implemented Handler for NOTIFY then there is no way to test. In fact this library is not consolidated, the only like she has on Github is my kkk - you will probably want to find something more tested and consolidated, sometimes something even outside the same Node and then you just create the bindings.

Your problem (or not) will find a library that implements the SSDP in the smartphone language/platform.

5

  • I will take a look, face can say that maybe Broadcast cause problems. I will make a prototype with Multicast and see if it presents a good result.

  • 2

    An alternative to decrease traffic, although UDP is compact by nature, would be for the client to send a broadcast when connecting and the server to respond only when requested, if the number of clients is not gigantic.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.