archytect
archytect

Reputation: 3725

multiple nodejs requests live search

I'm writing a domain search app, I've kept it simple to just checking availability of a .com domain. the basics of it works fine, the problem is when I have multiple requests, specifically multiple search()'s it gives me an error of

 { [Error: connect Unknown system errno 37]
  code: 'Unknown system errno 37',
  errno: 'Unknown system errno 37',
  syscall: 'connect' }


 events.js:72
         throw er; // Unhandled 'error' event
          ^
 Error: connect Unknown system errno 37
     at errnoException (net.js:863:11)
     at connect (net.js:726:19)
     at net.js:804:9
     at asyncCallback (dns.js:68:16)
    at Object.onanswer [as oncomplete] (dns.js:121:9)

what do I need to change or add to make it work? eventing? queuing?

(edited for dc5)

var searches = ['test1', 'test2', 'test3'];

search(searches.shift()); 

function chkconnections(z) {
     if (connections <= 0) {
         if (searches.length >= 1) {
            process.nextTick(function() {
                 search(searches.shift());
            });
         }
     }
 }

 function search(x) {
      dotCom.connect(port, host, function() {
      dotCom.write('domain ' + x + '.com\r\n');
      count++;
      connections++;
 });

    dotCom.on('data', function(data) {
        c++;
        if (c == 2) { 
            dotComStatus = data.split('\n')[1];
            dotCom.on('close', function() {
                connections--;
                chkconnections();
                count--;
                if (dotComStatus.indexOf("No match for domain") > -1)
                {
                    console.log(x + ".com is available");
                } else {
                    console.log(x + ".com is taken");
                }
            });
        }
    });
}   

Upvotes: 1

Views: 352

Answers (1)

dc5
dc5

Reputation: 12441

The way your code is structured, you have a single socket and you are attempting to call connect on it four times in succession. That is the root of your problem.

Other issues: you are using variables that haven't been declared or initialized yet. Strict mode can help catch problems like these (note the "use strict"; addition at the top.

The data that is passed back is a buffer - you will need to convert it to a string before using string methods on it.

If you restructure your code, moving the new Socket and on('data') logic within the search method, you'll see a much better result.

Something like this:

"use strict";

var port = 43;
var net = require('net');
var host = 'whois.internic.net';

search('test');
search('test1');
search('test2');
search('test3');

function search(x) {
    var dotCom = new net.Socket();

    dotCom.connect(port, host, function() {
        dotCom.write('domain ' + x + '.com\r\n');
    });

    var c = 0;
    var dotComStatus;

    dotCom.on('data', function(data) {
        c++;
        if (c == 2) {
            dotComStatus = data.toString().split('\n')[1];
            dotCom.on('close', function() {
                if (dotComStatus.indexOf("No match for domain") > -1) {
                    console.log("available");
                } else {
                    console.log("taken");
                }
            });
        }
    });
}

With a slight change, the logic to be made to search in sequence by only initiating the next search once the first is complete.

"use strict";

var port = 43;
var net = require('net');
var host = 'whois.internic.net';

var searches = [
    "test",
    "test1",
    "test2",
    "test3"
];


function search(x) {
    var dotCom = new net.Socket();

    dotCom.connect(port, host, function() {
        dotCom.write('domain ' + x + '.com\r\n');
    });

    var c = 0;
    var dotComStatus;

    dotCom.on('data', function(data) {
        c++;
        if (c == 2) {
            dotComStatus = data.toString().split('\n')[1];
            dotCom.on('close', function() {
                if (dotComStatus.indexOf("No match for domain") > -1) {
                    console.log("available");
                } else {
                    console.log("taken");
                }

                if(searches.length === 0) return;

                process.nextTick(function() {
                    search(searches.shift()); 
                });
            });
        }
    });
}

search(searches.shift());

If you want to search multiple TLD's for each second level domain you could do something like:

var tlds = ['.net', '.com', '.org'];
var names = ['test', 'test1', 'test2'];

for(var i = 0; i < names.length; ++i) {
    for(var j = 0; j < tlds.length; ++j) {
        search(names[i] + tlds[j]);
    }
}

and modify your search function to accept this type of parameter.

Upvotes: 2

Related Questions