La façon dont Facebook le fait est assez intéressante.
Une méthode courante pour effectuer de telles notifications consiste à interroger un script sur le serveur (à l'aide d'AJAX) à un intervalle donné (peut-être toutes les quelques secondes), pour vérifier si quelque chose s'est produit. Cependant, cela peut être assez intensif en réseau, et vous faites souvent des demandes inutiles, car rien ne s'est produit.
La façon dont Facebook le fait utilise l'approche comète, plutôt que d'interroger sur un intervalle, dès qu'un sondage est terminé, il en émet un autre. Cependant, chaque demande au script sur le serveur a un délai d'expiration extrêmement long, et le serveur ne répond à la demande qu'une fois que quelque chose s'est produit. Vous pouvez voir cela se produire si vous affichez l'onglet Console de Firebug sur Facebook, avec des demandes de script pouvant prendre quelques minutes. C'est vraiment très ingénieux, car cette méthode réduit immédiatement le nombre de demandes et la fréquence à laquelle vous devez les envoyer. Vous disposez désormais d'une infrastructure d'événements qui permet au serveur de «déclencher» des événements.
Derrière cela, en termes de contenu réel retourné par ces sondages, c'est une réponse JSON, avec ce qui semble être une liste d'événements et des informations à leur sujet. Il est cependant minifié, donc c'est un peu difficile à lire.
En termes de technologie réelle, AJAX est la voie à suivre ici, car vous pouvez contrôler les délais d'expiration des demandes et bien d'autres choses. Je recommanderais (cliché de débordement de pile ici) d'utiliser jQuery pour faire l'AJAX, cela éliminera beaucoup de problèmes de compatibilité croisée. En termes de PHP, vous pouvez simplement interroger une table de base de données du journal des événements dans votre script PHP et ne retourner au client que lorsque quelque chose se passe? Il y a, je pense, de nombreuses façons de mettre cela en œuvre.
Exécution:
Du côté serveur:
Il semble y avoir quelques implémentations de bibliothèques de comètes en PHP, mais pour être honnête, c'est vraiment très simple, quelque chose comme le pseudocode suivant:
while(!has_event_happened()) {
sleep(5);
}
echo json_encode(get_events());
La fonction has_event_happened vérifierait simplement si quelque chose s'est passé dans une table d'événements ou quelque chose, puis la fonction get_events retournerait une liste des nouvelles lignes de la table? Cela dépend vraiment du contexte du problème.
N'oubliez pas de modifier votre temps d'exécution PHP max, sinon il expirera tôt!
Côté client:
Jetez un oeil au plugin jQuery pour faire l'interaction Comet:
Cela dit, le plugin semble ajouter un peu de complexité, c'est vraiment très simple sur le client, peut-être (avec jQuery) quelque chose comme:
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
});
Le tout dépend beaucoup de la façon dont votre architecture existante est constituée.
Mettre à jour
Alors que je continue à recevoir des votes positifs à ce sujet, je pense qu'il est raisonnable de se rappeler que cette réponse a 4 ans. Le Web s'est développé à un rythme très rapide, alors soyez attentif à cette réponse.
J'ai eu le même problème récemment et fait des recherches sur le sujet.
La solution proposée est appelée longue interrogation, et pour l'utiliser correctement, vous devez être sûr que votre requête AJAX a un "grand" délai d'attente et toujours faire cette demande après la fin actuelle (délai d'attente, erreur ou succès).
Interrogation longue - Client
Ici, pour garder le code court, j'utiliserai jQuery:
Il est important de se rappeler que (à partir des documents jQuery ):
Interrogation longue - Serveur
Ce n'est pas dans une langue spécifique, mais ce serait quelque chose comme ceci:
Ici,
hasTimedOut
s'assurera que votre code n'attend pas éternellement etanythingHappened
vérifiera si un événement se produit. C'estsleep
pour libérer votre thread pour faire d'autres choses alors que rien ne se passe. Leevents
renvoie un dictionnaire d'événements (ou toute autre structure de données que vous préférez) au format JSON (ou tout autre que vous préférez).Cela résout sûrement le problème, mais, si vous êtes préoccupé par l'évolutivité et la performance comme je l'étais lors de mes recherches, vous pourriez envisager une autre solution que j'ai trouvée.
Solution
Utilisez des prises!
Côté client, pour éviter tout problème de compatibilité, utilisez socket.io . Il essaie d'utiliser directement le socket et a des solutions de rechange à d'autres solutions lorsque les sockets ne sont pas disponibles.
Côté serveur, créez un serveur à l'aide de NodeJS (exemple ici ). Le client s'abonnera à ce canal (observateur) créé avec le serveur. Chaque fois qu'une notification doit être envoyée, elle est publiée sur ce canal et le souscripteur (client) est notifié.
Si vous n'aimez pas cette solution, essayez APE ( Ajax Push Engine ).
J'espère que j'ai aidé.
la source
hasTimedOut()
?Selon un diaporama sur le système de messagerie de Facebook, Facebook utilise la technologie des comètes pour «pousser» les messages vers les navigateurs Web. Le serveur de comètes de Facebook est construit sur le serveur Web Erlang open source mochiweb.
Dans l'image ci-dessous, l'expression "groupes de canaux" signifie "serveurs comètes".
De nombreux autres grands sites Web construisent leur propre serveur de comètes, car il existe des différences entre les besoins de chaque entreprise. Mais construire votre propre serveur de comète sur un serveur de comète open source est une bonne approche.
Vous pouvez essayer icomet , un serveur de comètes C1000K C ++ construit avec libevent. icomet fournit également une bibliothèque JavaScript, elle est facile à utiliser aussi simple que:
icomet prend en charge une large gamme de navigateurs et de systèmes d'exploitation, y compris Safari (iOS, Mac), IE (Windows), Firefox, Chrome, etc.
la source
Facebook utilise MQTT au lieu de HTTP. Pousser vaut mieux que d'interroger. Via HTTP, nous devons interroger le serveur en continu, mais via le serveur MQTT, le message est envoyé aux clients.
Comparaison entre MQTT et HTTP: http://www.youtube.com/watch?v=-KNPXPmx88E
Remarque: mes réponses conviennent le mieux aux appareils mobiles.
la source
Un problème important avec l'interrogation longue est la gestion des erreurs. Il existe deux types d'erreurs:
La demande peut expirer, auquel cas le client doit rétablir immédiatement la connexion. Il s'agit d'un événement normal lors d'une longue interrogation lorsque aucun message n'est arrivé.
Une erreur de réseau ou une erreur d'exécution. Il s'agit d'une erreur réelle que le client doit accepter gracieusement et attendre que le serveur revienne en ligne.
Le problème principal est que si votre gestionnaire d'erreurs rétablit immédiatement la connexion également pour une erreur de type 2, les clients DOS le serveur.
Les deux réponses avec l'exemple de code manquent cela.
la source