Solución:
Encontré a alguien que logra esto con un uso muy inteligente de los nativos Image
objeto.
Desde su fuente, esta es la función principal (tiene dependencias en otras partes de la fuente, pero entiendes 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.
Actualizar: Se ha eliminado el enlace anterior. 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 arroja un net::ERR_NAME_NOT_RESOLVED
error. Si alguien puede verificar una solución alternativa, la pondré como la respuesta aceptada.
Ping es ICMP, pero si hay algún puerto TCP abierto en el servidor remoto, podría lograrse 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:
poner ping.html en el servidor con o sin contenido, en javascript haga lo mismo que a continuación:
<script>
function ping(){
$.ajax({
url: 'ping.html',
success: function(result){
alert('reply');
},
error: function(result){
alert('timeout/error');
}
});
}
</script>