最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

JavaScript: Find Local WebSocket Servers - Stack Overflow

programmeradmin3浏览0评论

I'm experimenting at the moment with trying to detect local network websocket servers (that I wrote) within an IP range. I have one running on the network and I would like my script to detect it (and others on the same port).

At the moment I can acplish this with a for loop and just try and create a list depending on whether I can successfully connect to a server on that IP. That however is very slow and inefficient. Any ideas how to do this quickly and efficiently?

A snippet of my code:

var port = 1234;
var ip_range = "192.168.1.";
var servers = [];
var i = 0;

function findServers() {
    if ( i > 255 ) {
        return;
    }
    try {
        var host = "ws://"+ip_range+i+":"+port;
        var socket = new WebSocket(host);
        socket.onopen = function(){
            console.log("Success: " + socket.url);
            servers.push(socket.url);
            i++;
            findServers();
        };
        socket.onerror = function(error){
            console.log("Error: " + socket.url);
            i++;
            findServers();
        };
    } catch (e) {
        console.log("Error: " + socket.url);
        i++;
        findServers();
    }
}

If it helps I wrote the socket server so I can modify the code if need be.

I'm experimenting at the moment with trying to detect local network websocket servers (that I wrote) within an IP range. I have one running on the network and I would like my script to detect it (and others on the same port).

At the moment I can acplish this with a for loop and just try and create a list depending on whether I can successfully connect to a server on that IP. That however is very slow and inefficient. Any ideas how to do this quickly and efficiently?

A snippet of my code:

var port = 1234;
var ip_range = "192.168.1.";
var servers = [];
var i = 0;

function findServers() {
    if ( i > 255 ) {
        return;
    }
    try {
        var host = "ws://"+ip_range+i+":"+port;
        var socket = new WebSocket(host);
        socket.onopen = function(){
            console.log("Success: " + socket.url);
            servers.push(socket.url);
            i++;
            findServers();
        };
        socket.onerror = function(error){
            console.log("Error: " + socket.url);
            i++;
            findServers();
        };
    } catch (e) {
        console.log("Error: " + socket.url);
        i++;
        findServers();
    }
}

If it helps I wrote the socket server so I can modify the code if need be.

Share Improve this question edited Nov 30, 2014 at 17:16 trvo asked Nov 30, 2014 at 16:59 trvotrvo 6851 gold badge11 silver badges24 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

The key to getting fast results with trial socket connections like you are doing is two-fold:

  1. Run multiple connection attempts in parallel (as many as possible, but not too many)
  2. Control the timeout for servers that are not there (the default timeout built into the WebSocket is very long so this short circuits the long wait which makes the overall process of checking a lot of sockets - most of which don't exist - take a long time).

You do not have to use WebWorkers for this task and, in fact, I think it's probably less efficient to use WebWorkers because there's no need to create a new thread for each socket. Socket programming in Javascript is entirely async so you can keep many of them going at once just fine and be very efficient about it.

Here's an entirely async way that runs multiple socket requests at the same time and should be more efficient than using WebWorkers. It will probably take some experimentation to see how many active WebSocket requests can be open at once. This examples passes 20 as that argument, but you can try more or less. The more the better (more requests in parallel) until you run into browser limits for active sockets at once.

A key parameter in how quickly this gets your result is setting the timeout value for how long you're going to wait for a webSocket response. In this implementation, I let you pass that in as an argument and again, you can experiment with appropriate values. Since these are all local servers, you're looking for, I'd expect something like just a few seconds (2000-4000ms) would probably work for you and generate much faster results than the normal WebSocket timeout.

function findServers(port, ipBase, ipLow, ipHigh, maxInFlight, timeout, cb) {
    var ipCurrent = +ipLow, numInFlight = 0, servers = [];
    ipHigh = +ipHigh;

    function tryOne(ip) {
        ++numInFlight;
        var address = "ws://" + ipBase + ip + ":" + port;
        var socket = new WebSocket(address);
        var timer = setTimeout(function() {
            console.log(address + " timeout");
            var s = socket;
            socket = null;
            s.close();
            --numInFlight;
            next();
        }, timeout);
        socket.onopen = function() {
            if (socket) {
                console.log(address + " success");
                clearTimeout(timer);
                servers.push(socket.url);
                --numInFlight;
                next();
            }
        };
        socket.onerror = function(err) {
            if (socket) {
                console.log(address + " error");
                clearTimeout(timer);
                --numInFlight;
                next();
            }
        }
    }

    function next() {
        while (ipCurrent <= ipHigh && numInFlight < maxInFlight) {
            tryOne(ipCurrent++);
        }
        // if we get here and there are no requests in flight, then
        // we must be done
        if (numInFlight === 0) {
            console.log(servers);
            cb(servers);
        }
    }

    next();
}

findServers(1234, "192.168.1.", 1, 255, 20, 4000, function(servers) {
    console.log(servers);
});
发布评论

评论列表(0)

  1. 暂无评论