NodeJS: Ein kleiner UDP-Autodiscovery Server mit Node.js

Für ein neues Programm war es erforderlich die Konfiguration, wie z.B. Datenbank-Server, Benutzer, Passwort, etc automatisch im netzwerk zur verfügung zu stellen.
Das Programm sendet hierbei via Broadcast UDP-Pakete an alle Geräte im selben Netzwerk – und alle Geräte welche sich dafür Verantwortlich fühlen, antworten dem Programm dann.
In unserem Fall hier soll es ein Node.js Server sein welcher dem Programm eine bestimmte Konfiguration zur verfügung stellt.
Node.js habe ich aufgrund der Performace und Plattform-unabhängigkeit gewählt. Außerdem gibt es für Node.js spezielle tools mit denen man ein Node-Script unter Windows einfacher als Dienst einrichten kann als sich selbst ein Dienst-Setup für einen C# Dienst zu bauen.

Um UDP Pakete mit Node.js versenden zu können, braucht man die Klasse dgram welche ab node.js Version 0.10 bereits teil von Node.js selbst ist, womit keine externen Abhängigkeiten benötigt werden.

Hier der grundelegende Code um einen UDP-Server auf Port 15000 zu starten:

1
2
3
4
5
6
7
var PORT = 15000;                           // Server auf Port 15000
var HOST = '0.0.0.0';                       // Server auf allen verfügbaren IPs
 
var dgram = require('dgram');               // dgram Klasse für UDP-Verbindungen
var server = dgram.createSocket('udp4');    // IPv4 UDP Socket erstellen
 
server.bind(PORT, HOST);                    // Den Socket/Server an IP und Port binden

Nun können die verschiedenen Events ausgewertet werden.
Um z.B. eine Ausgabe anzeigen zu lassen, sobald der Socket gebunden wurde, kann man das „listening“ Event wie folgt auswerten:

1
2
3
4
server.on('listening', function () {
    var srvadr = server.address();
    console.log('UDP Server listening on ' + srvadr.address + ":" + srvadr.port);
});

Aus Ausgabe würde hier nach dem starten des Scriptes folgendes in der Konsole erscheinen:
UDP Server listening on 127.0.0.1:15000

Nun wollen wir beim Eintreffen einer UDP Nachricht dem Versender der Nachricht antworten.
Hierfür wird das „message“ Event ausgewertet:

1
2
3
4
server.on('message', function (message, remote) {
    console.log(remote.address + ':' + remote.port +' - ' + message);
    UDPSend("{Ein,diverser,JSON,String}",remote.address,PORT);
});

Sobald eine Nachricht eintrifft wird der String „{Ein,diverser,JSON,String}“ mit der Funktion „UDPSEND“ zurück an den Versender der UDP Nachricht geschickt.
Statt dem String „{Ein,diverser,JSON,String}“ eignet sich wie in unserem Fall auch jede andere Art von JSON Inhalten.
Der Code der Funktion UDPSEND() ist wie folgt:

1
2
3
4
5
6
7
8
9
10
11
function UDPSend(message,HOST,PORT)
{
    var client = dgram.createSocket('udp4'); // Neuen Socket zum Client aufbauen
    var message = new Buffer(message);
 
    client.send(message, 0, message.length, PORT, HOST, function(err, bytes) 
    {
        console.log('UDP message sent to ' + HOST +':'+ PORT); // Ausgabe der Nachricht
        client.close(); // Bei erfolgreichen Senden, die Verbindung zum CLient schließen
    });
}

Hier wird ein neuer Socket für die Kommunikation zum Client aufgebaut und diesem ebenfalls über UDP/Port 15000 über die Methode send() die Antwort (der JSON String) geschickt.

Hier noch einmal das Komplette Script des Servers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//###############################################################################################
//## Node.js UDP-AutoDiscovery Server
//###############################################################################################
var PORT = 15000;                           // Server auf Port 15000
var HOST = '0.0.0.0';                       // Server auf allen verfügbaren IPs
var dgram = require('dgram');               // dgram Klasse für UDP-Verbindungen
var server = dgram.createSocket('udp4');     // IPv4 UDP Socket erstellen
//-----------------------------------------------------------------------------------------------
server.bind(PORT, HOST);                     // Den Socket/Server an IP und Port binden
//-----------------------------------------------------------------------------------------------
server.on('message', function (message, remote) {
    console.log(remote.address + ':' + remote.port +' - ' + message);
    UDPSend("{Ein,diverser,JSON,String}",remote.address,PORT);
});
//-----------------------------------------------------------------------------------------------
server.on('listening', function () {
    var srvadr = server.address();
    console.log('UDP Server listening on ' + srvadr.address + ":" + srvadr.port);
});
//-----------------------------------------------------------------------------------------------
function UDPSend(message,HOST,PORT)
{
    var client = dgram.createSocket('udp4'); // Neuen Socket zum Client aufbauen
    var message = new Buffer(message);
 
    client.send(message, 0, message.length, PORT, HOST, function(err, bytes) 
    {
        console.log('UDP message sent to ' + HOST +':'+ PORT); // Ausgabe der Nachricht
        client.close(); // Bei erfolgreichen Senden, die Verbindung zum CLient schließen
    });
}
//-----------------------------------------------------------------------------------------------

Ich wünsche ich viel Spaß damit! 🙂
PS: Natürlich wurde hier nicht an Fehler-Behandlung gedacht um den Code möglichst klein zu halten.
Vor dem Produktiv-Einsatz also bitte selbst dafür sorgen das Fehler behandelt werden!

One Response to NodeJS: Ein kleiner UDP-Autodiscovery Server mit Node.js

  1.  

    (auch wenn das hier schon alles etwas älter ist 😉 )
    Hi,
    netter kleiner Einstiegspunkt, war hilfreich – aber eine Frage:

    Ist es beabsichtigt, dass der Server auf ‚PORT‘ antwortet und nicht auf ‚remote.port‘? (Zeile 13)

    Gruß.

leave your comment


*

Unterstütze den Frickelblog!