It seems this blog is turning into mostly Node.js posts, but I’ve been experimenting with it more than other languages. As part of my Protos server, I wanted to create a control panel that could manage all the server functions, including monitoring services. It is pretty simple to do actually.
Using the net module of Node.js, you can easily create TCP streams. Here is a simple example, including the primary listeners:
stream.on('connect', function(){
console.log('connected');
});
stream.on('data', function(chunk){
console.log('data: ' + chunk);
})
stream.on('error', function(error){
console.log('error: ' + error);
})
stream.on('end', function(){
console.log('terminated');
})
The action listeners are self-explanatory, and clearly describe what the example is doing. If we used the above example to connect to an SMTP server, the results would be just as what we would expect if we were to perform a telnet to port 25:
connected
data: 220-vps8 ESMTP Exim 4.69 #1 Tue, 09 Nov 2010 23:31:32 -0500
220-We do not authorize the use of this system to transport unsolicited,
220 and/or bulk e-mail.
In practice though, we do not really need all 4 of the aforementioned listeners. We really just need connect and error. As defined by the Node.JS, there are a few different ways to kill the TCP stream that we created with createConnection(). Within the ‘connect’ listener, the connection is successful, so we can use stream.end(). However, on the ‘error’ listener, we will need to handle the closing of the stream with the stream.destroy() method.
The following examples puts the previous words into action:
var stream = net.createConnection(port, address);
// listen for connection
stream.on('connect', function() {
// connection success
console.log('connected');
stream.end(); // close the stream
});
// listen for any errors
stream.on('error', function(error) {
console.log('error: ' + error);
stream.destroy(); // close the stream
// note: we use destroy() because of the errors
})
Now we can take this example, and check a list of daemons running on different ports. We can create an object for each daemon and then iterate through an array of these objects, creating a stream to each one and logging the results:
var address = '127.0.0.1';
var daemons = []; // our array of services
function Daemon(name, port) {
this.name = name;
this.port = port;
}
// add new Daemon objects to array
daemons.push(new Daemon('smtp', 25));
daemons.push(new Daemon('pop3', 110));
daemons.push(new Daemon('http', 80));
daemons.push(new Daemon('imap4', 143));
daemons.push(new Daemon('ftp', 21));
daemons.push(new Daemon('mysql', 3306));
daemons.push(new Daemon('whm', 2086));
// loop through each daemon in the array
daemons.forEach(function(d) {
// create the TCP stream to the server
var stream = net.createConnection(d.port, address);
// listen for connection
stream.on('connect', function(){
// connection success
console.log('[' + d.name + ']\t connected');
stream.end(); // close the stream
});
// listen for any errors
stream.on('error', function(error){
console.log('[' + d.name + ']\t error: ' + error);
stream.destroy(); // close the stream
// note: we use destroy() because of the errors
})
});
The results would look like this (if all the connections were successful):
[smtp] connected
[ftp] connected
[imap4] connected
[http] connected
[pop3] connected
[mysql] connected
[whm] connected
I am working on a web page variant of this script, and will eventually host it on my Github repository.