JavaScript:查找本地WebSocket服务器

JavaScript:查找本地WebSocket服务器,javascript,websocket,Javascript,Websocket,我正在尝试检测IP范围内的本地网络websocket服务器(我写的)。我有一个在网络上运行,我希望我的脚本能够检测到它(以及同一端口上的其他端口) 目前,我可以通过for循环来实现这一点,只需尝试创建一个列表,这取决于我是否能够成功连接到该IP上的服务器。然而,这是非常缓慢和低效的。有没有办法快速有效地做到这一点 我的代码片段: var port = 1234; var ip_range = "192.168.1."; var servers = []; var i = 0; function

我正在尝试检测IP范围内的本地网络websocket服务器(我写的)。我有一个在网络上运行,我希望我的脚本能够检测到它(以及同一端口上的其他端口)

目前,我可以通过for循环来实现这一点,只需尝试创建一个列表,这取决于我是否能够成功连接到该IP上的服务器。然而,这是非常缓慢和低效的。有没有办法快速有效地做到这一点

我的代码片段:

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();
    }
}

如果有帮助的话,我编写了套接字服务器,以便在需要时修改代码。

像您这样使用试用套接字连接获得快速结果的关键有两个方面:

  • 并行运行多个连接尝试(尽可能多,但不要太多)
  • 控制不存在的服务器的超时(WebSocket中内置的默认超时非常长,因此这缩短了长时间的等待,这使得检查大量套接字(其中大多数不存在)的整个过程需要很长时间)
  • 您不必使用WebWorkers来完成此任务,事实上,我认为使用WebWorkers可能效率较低,因为不需要为每个套接字创建新线程。Javascript中的套接字编程是完全异步的,因此您可以让许多套接字同时正常运行,并且非常高效

    这是一种完全异步的方式,可以同时运行多个套接字请求,应该比使用WebWorkers更有效。可能需要进行一些实验才能确定一次可以打开多少活动WebSocket请求。此示例将20作为该参数传递,但您可以多多少少尝试。越多越好(并行请求越多),直到您立即遇到活动套接字的浏览器限制

    这将以多快的速度获得结果,其中一个关键参数是设置等待webSocket响应的超时值。在这个实现中,我让您将其作为参数传入,然后再次尝试使用适当的值。由于这些都是您正在寻找的本地服务器,因此我预计几秒钟(2000-4000ms)的时间可能对您有效,并生成比正常WebSocket超时快得多的结果

    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);
    });
    
    函数查找服务器(端口、ipBase、ipLow、ipHigh、maxInFlight、超时、cb){
    var ipCurrent=+ipLow,numInFlight=0,服务器=[];
    ipHigh=+ipHigh;
    功能tryOne(ip){
    ++努明飞行;
    var address=“ws://”+ipBase+ip+:“+port;
    var套接字=新的WebSocket(地址);
    var timer=setTimeout(函数(){
    控制台日志(地址+“超时”);
    var s=插座;
    socket=null;
    s、 close();
    --努明飞行;
    next();
    },超时);
    socket.onopen=函数(){
    中频(插座){
    控制台日志(地址+“成功”);
    清除超时(计时器);
    推送(socket.url);
    --努明飞行;
    next();
    }
    };
    socket.onerror=函数(err){
    中频(插座){
    控制台日志(地址+“错误”);
    清除超时(计时器);
    --努明飞行;
    next();
    }
    }
    }
    函数next(){
    
    虽然(ipCurrent Thank@jfriend)不得不更改此行以适应端口
    var address=“ws://“+ipBase+ip+”:“+port;
    ,并且能够将等待时间缩短到1000ms,但该示例运行得非常好。