¿Es posible hacer ping a un servidor desde Javascript?
Estoy creando una aplicación web que requiere verificar si los servidores remotos están en línea o no. Cuando lo ejecuto desde la línea de comando, la carga de mi página sube hasta 60 (para 8 entradas, escalará linealmente con más).
Decidí seguir la ruta de hacer ping por parte del usuario. De esta manera, puedo cargar la página y hacer que esperen los datos de "el servidor está en línea" mientras navega por mi contenido.
Si alguien tiene la respuesta a la pregunta anterior, o si conoce una solución para mantener mi página cargando rápidamente, definitivamente se lo agradecería.
Encontré a alguien que logra esto con un uso muy inteligente del Image
objeto nativo.
Desde su fuente, esta es la función principal (depende de otras partes de la fuente, pero ya se entiende la idea).
function Pinger_ping(ip, callback) {
if(!this.inUse) {
this.inUse = true;
this.callback = callback
this.ip = ip;
var _that = this;
this.img = new Image();
this.img.onload = function() {_that.good();};
this.img.onerror = function() {_that.good();};
this.start = new Date().getTime();
this.img.src = "http://" + ip;
this.timer = setTimeout(function() { _that.bad();}, 1500);
}
}
Esto funciona en todos los tipos de servidores que he probado (servidores web, servidores ftp y servidores de juegos). También funciona con puertos. Si alguien encuentra un caso de uso que falla, publíquelo en los comentarios y actualizaré mi respuesta.
Actualización : el enlace anterior ha sido eliminado. Si alguien encuentra o implementa lo anterior, comente y lo agregaré a la respuesta.
Actualización 2 : @trante fue lo suficientemente amable como para proporcionar un jsFiddle.
http://jsfiddle.net/GSSCD/203/
Actualización 3 : @Jonathon creó un repositorio de GitHub con la implementación.
https://github.com/jdfreder/pingjs
Actualización 4 : Parece que esta implementación ya no es confiable. La gente también informa que Chrome ya no lo admite todo, lo que genera un net::ERR_NAME_NOT_RESOLVED
error. Si alguien puede verificar una solución alternativa, la pondré como la respuesta aceptada.
El ping es ICMP, pero si hay algún puerto TCP abierto en el servidor remoto se podría lograr así:
function ping(host, port, pong) {
var started = new Date().getTime();
var http = new XMLHttpRequest();
http.open("GET", "http://" + host + ":" + port, /*async*/true);
http.onreadystatechange = function() {
if (http.readyState == 4) {
var ended = new Date().getTime();
var milliseconds = ended - started;
if (pong != null) {
pong(milliseconds);
}
}
};
try {
http.send(null);
} catch(exception) {
// this is expected
}
}
puedes probar esto:
coloque ping.html en el servidor con o sin contenido, en javascript haga lo mismo que se muestra a continuación:
<script>
function ping(){
$.ajax({
url: 'ping.html',
success: function(result){
alert('reply');
},
error: function(result){
alert('timeout/error');
}
});
}
</script>
No se puede hacer "ping" directamente en javascript. Puede haber algunas otras formas:
- Ájax
- Usando un subprograma de Java con isReachable
- Escribir un script del lado del servidor que haga ping y use AJAX para comunicarse con el script del lado del servidor
- También es posible que puedas hacer ping en flash (actionscript)