我目前正在尝试尝试检测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 的效率可能较低,因为不需要为每个套接字创建一个新线程。 Javascript中的套接字编程是完全异步的,因此您可以同时保持其中的许多运行,并且非常高效。
这是一种完全异步的方式,可以同时运行多个套接字请求,并且应该比使用 WebWorkers 更有效。 可能需要一些实验才能看到一次可以打开多少个活动的 WebSocket 请求。 此示例传递 20 作为该参数,但您可以尝试更多或更少。 越多越好(并行请求越多(,直到您一次遇到活动套接字的浏览器限制。
获取结果的速度的一个关键参数是设置等待 webSocket 响应的时间的超时值。 在此实现中,我让您将其作为参数传递,然后再次尝试适当的值。 由于这些都是您正在寻找的本地服务器,我希望只有几秒钟(2000-4000 毫秒(可能会为您工作,并且生成的结果比正常的 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);
});