web-dev-qa-db-fra.com

Quelle technologie Google Drive utilise-t-il pour obtenir des mises à jour en temps réel?

Quelle technologie Google Drive utilise-t-il pour faire en temps réel?

Lorsque je tape un document Google Drive auquel accèdent plusieurs utilisateurs, l'onglet Chrome Réseau des outils de développement indique qu'il n'y a pas de WebSockets.

Je vois que les deux types les plus fréquents d'appels AJAX ont soit "bind?" Soit "save?" Dans l'URL. "Save?" POST request sont faites à chaque fois que je tape, ce qui est logique AJAX pour envoyer des mises à jour au serveur.

Lorsqu'un autre utilisateur tape, le plus récent "bind?" L'appel GET reste ouvert et la quantité de données transférées via cette connexion augmente. Périodiquement, les "binds" sont fermés et de nouveaux s'ouvrent, et la logique semble être fonction de la durée et de la taille des données.

Ce n'est pas une longue interrogation, car lorsque le serveur envoie des mises à jour, il ne termine pas la réponse.

Il ne semble pas s'agir d'événements envoyés par le serveur, car le type de contenu est "text/plain" au lieu de "text/stream".

Y a-t-il un nom pour ce que Google fait? Si oui, comment puis-je essayer de mettre en œuvre cela?

Chrome Dev Tools - editing a Google Drive document

37
Max Heiber

Existe-t-il un nom pour la solution de Google pour les mises à jour en temps réel dans Drive (telles que "interrogation longue" ou "sockets")?

Il n'avait pas de nom jusqu'à présent. Je l'appellerai "sans interrogation", pour contraster avec l'interrogation et l'interrogation longue.

Avec l'interrogation, le client envoie périodiquement des requêtes pour de nouvelles données.

Avec l'interrogation longue, le client interroge les données et le serveur conserve la demande, mettant fin à la réponse avec les mises à jour lorsqu'il y a des mises à jour.

L'absence d'interrogation (ce que fait Google Drive) tire parti de la façon dont le navigateur peut lire les données du corps d'une demande avant la fin de la demande. Ainsi, à mesure que les collaborateurs effectuent davantage de saisie et de modification, le serveur ajoute plus de données à la demande actuelle. Si certaines limites sont respectées (longueur du contenu ou durée de la requête), la requête se termine et le client lance une nouvelle requête avec le serveur.

Comment puis-je essayer de mettre en œuvre cela?

Pour que le client envoie des mises à jour au serveur: cela peut être fait avec des POST normaux.

Pour que le client s'abonne aux mises à jour depuis le serveur:

  • Le client envoie un GET pour un flux de mise à jour, puis commence à lire le corps de la réponse avant que la réponse ne soit terminée.

    Les objets XHR peuvent émettre des événements progress avant la fin de la demande. La réponse (partielle) est accessible à l'aide de xhr.responseText. ~~ Il n'y a pas de moyen simple de surveiller les progrès avec fetchencore (à partir de mai 2016). ~~ Lorsque vous utilisez fetch, vous pouvez surveiller les progrès en - consommant le res.body ReadableStream .

  • Le client doit lancer une nouvelle demande à la fin de la demande en cours.

Le serveur doit:

  • Gardez une trace des clients abonnés à quels flux de mise à jour.
  • Lorsqu'une demande arrive pour un flux de mise à jour particulier, écrivez des données dans la réponse, mais ne terminez pas la réponse tant que la quantité de données n'est pas importante ou qu'un délai d'attente n'est pas respecté.

Le non-scrutin semble supérieur au long-polling, à mon avis, même si je n'y ai pas beaucoup joué. L'interrogation longue oblige à un compromis entre la latence et la taille du message (compte tenu d'un taux constant de mises à jour), un échange sans interrogation n'a pas à faire. Un autre inconvénient de l'interrogation longue est qu'elle peut conduire à de nombreuses requêtes HTTP, payant la surcharge de HTTP à chaque fois.

Le gros avantage de la non-polling par rapport aux WebSockets est que la non-polling est prise en charge par tous les navigateurs, bien que la prise en charge de WebSocket soit plutôt bonne - IE10 + .

48
Max Heiber