La forma en que Facebook hace esto es bastante interesante.
Un método común para hacer tales notificaciones es sondear un script en el servidor (usando AJAX) en un intervalo dado (tal vez cada pocos segundos), para verificar si algo ha sucedido. Sin embargo, esto puede ser bastante intensivo en la red, y a menudo haces solicitudes sin sentido, porque no ha pasado nada.
La forma en que Facebook lo hace es usar el enfoque del cometa, en lugar de sondear en un intervalo, tan pronto como se completa una encuesta, emite otra. Sin embargo, cada solicitud al script en el servidor tiene un tiempo de espera extremadamente largo, y el servidor solo responde a la solicitud una vez que algo ha sucedido. Puede ver que esto sucede si abre la pestaña Consola de Firebug mientras está en Facebook, y las solicitudes de un script posiblemente demoren minutos. Realmente es bastante ingenioso, ya que este método reduce inmediatamente tanto el número de solicitudes como la frecuencia con la que tiene que enviarlas. Efectivamente, ahora tiene un marco de eventos que permite al servidor 'disparar' eventos.
Detrás de esto, en términos del contenido real devuelto por esas encuestas, es una respuesta JSON, con lo que parece ser una lista de eventos e información sobre ellos. Sin embargo, está minimizado, por lo que es un poco difícil de leer.
En términos de la tecnología real, AJAX es el camino a seguir aquí, porque puede controlar los tiempos de espera de solicitudes y muchas otras cosas. Recomiendo (haga clic aquí en el cliché de desbordamiento) usar jQuery para hacer el AJAX, eliminará muchos de los problemas de compatibilidad cruzada. En términos de PHP, ¿podría simplemente sondear una tabla de base de datos de registro de eventos en su script PHP y solo regresar al cliente cuando sucede algo? Hay, espero, muchas formas de implementar esto.
Implementar:
Lado del servidor:
Parece que hay algunas implementaciones de bibliotecas de cometas en PHP, pero para ser sincero, realmente es muy simple, algo así como el siguiente pseudocódigo:
while(!has_event_happened()) {
sleep(5);
}
echo json_encode(get_events());
La función has_event_happened solo verificaría si algo sucedió en una tabla de eventos o algo así, y luego la función get_events devolvería una lista de las nuevas filas en la tabla. Depende del contexto del problema realmente.
¡No olvides cambiar el tiempo máximo de ejecución de PHP, de lo contrario, se agotará pronto!
Lado del cliente:
Eche un vistazo al complemento jQuery para realizar la interacción Comet:
Dicho esto, el complemento parece agregar un poco de complejidad, realmente es muy simple para el cliente, tal vez (con jQuery) algo así como:
function doPoll() {
$.get("events.php", {}, function(result) {
$.each(result.events, function(event) { //iterate over the events
//do something with your event
});
doPoll();
//this effectively causes the poll to run again as
//soon as the response comes back
}, 'json');
}
$(document).ready(function() {
$.ajaxSetup({
timeout: 1000*60//set a global AJAX timeout of a minute
});
doPoll(); // do the first poll
});
Todo depende mucho de cómo se arma su arquitectura existente.
Actualizar
A medida que sigo recibiendo votos a favor sobre esto, creo que es razonable recordar que esta respuesta tiene 4 años. La web ha crecido a un ritmo realmente rápido, así que tenga en cuenta esta respuesta.
Tuve el mismo problema recientemente e investigué sobre el tema.
La solución dada se llama sondeo largo y, para usarla correctamente, debe asegurarse de que su solicitud de AJAX tenga un tiempo de espera "grande" y hacer siempre esta solicitud después de que finalice el tiempo actual (tiempo de espera, error o éxito).
Encuesta larga - Cliente
Aquí, para mantener el código corto, usaré jQuery:
Es importante recordar que (de los documentos de jQuery ):
Sondeo largo: servidor
No está en ningún idioma específico, pero sería algo como esto:
Aquí,
hasTimedOut
se asegurará de que su código no espere para siempre yanythingHappened
verificará si sucedió algún evento. Elsleep
es para liberar su hilo para hacer otras cosas mientras no pasa nada. Elevents
volverá un diccionario de eventos (o cualquier otra estructura de datos es posible que prefiera) en formato JSON (o cualquier otro que prefiera).Seguramente resuelve el problema, pero, si está preocupado por la escalabilidad y el rendimiento como lo estaba yo al investigar, podría considerar otra solución que encontré.
Solución
Use enchufes!
En el lado del cliente, para evitar problemas de compatibilidad, use socket.io . Intenta usar socket directamente y tiene retrocesos a otras soluciones cuando no hay sockets disponibles.
En el lado del servidor, cree un servidor usando NodeJS (ejemplo aquí ). El cliente se suscribirá a este canal (observador) creado con el servidor. Cada vez que se debe enviar una notificación, se publica en este canal y se notifica al suscriptor (cliente).
Si no le gusta esta solución, pruebe APE ( Ajax Push Engine ).
Espero haber ayudado.
fuente
hasTimedOut()
?Según una presentación de diapositivas sobre el sistema de mensajería de Facebook, Facebook utiliza la tecnología cometa para "enviar" mensajes a los navegadores web. El servidor cometa de Facebook se basa en el servidor web Erlang de código abierto mochiweb.
En la imagen a continuación, la frase "grupos de canales" significa "servidores de cometas".
Muchos otros sitios web grandes construyen su propio servidor cometa, porque hay diferencias entre las necesidades de cada empresa. Pero construir su propio servidor cometa en un servidor cometa de código abierto es un buen enfoque.
Puede probar icomet , un servidor cometa C1000K C ++ construido con libevent. icomet también proporciona una biblioteca de JavaScript, es fácil de usar tan simple como:
icomet admite una amplia gama de navegadores y sistemas operativos, incluidos Safari (iOS, Mac), IE (Windows), Firefox, Chrome, etc.
fuente
Facebook usa MQTT en lugar de HTTP. Empujar es mejor que votar. A través de HTTP necesitamos sondear el servidor continuamente, pero a través del servidor MQTT envía el mensaje a los clientes.
Comparación entre MQTT y HTTP: http://www.youtube.com/watch?v=-KNPXPmx88E
Nota: mis respuestas se ajustan mejor a dispositivos móviles.
fuente
Un problema importante con las encuestas largas es el manejo de errores. Hay dos tipos de errores:
La solicitud puede expirar, en cuyo caso el cliente debe restablecer la conexión de inmediato. Este es un evento normal en sondeos largos cuando no ha llegado ningún mensaje.
Un error de red o un error de ejecución. Este es un error real que el cliente debe aceptar con gracia y esperar a que el servidor vuelva a estar en línea.
El problema principal es que si su controlador de errores restablece la conexión inmediatamente también para un error de tipo 2, los clientes pondrían DOS en el servidor.
Ambas respuestas con código de muestra pierden esto.
fuente