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.
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
– Guilherme Nascimento
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.
– Pedro Henrique
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– Guilherme Nascimento
Can’t use DNS? Simplify.
– Bacco
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.
– Pedro Henrique