it-swarm.com.de

Warum wird Polling in der Webprogrammierung akzeptiert?

Ich arbeite derzeit an einem Ruby on Rails Projekt, das eine Liste von Bildern zeigt.

Ein Muss für dieses Projekt ist, dass neue Beiträge in Echtzeit angezeigt werden, ohne dass die Webseite aktualisiert werden muss. Nachdem ich eine Weile gesucht habe, bin ich auf einige JavaScript-Lösungen und -Dienste gestoßen, wie z. B. PubNub; Keine der angebotenen Lösungen ergab jedoch überhaupt einen Sinn.

In der JavaScript-Lösung ( Polling ) geschieht Folgendes:

  • Benutzer 1 zeigt die Liste der Fotos an.
  • Im Hintergrund fragt der JavaScript-Code jede Sekunde einen Endpunkt ab, um festzustellen, ob ein neuer Beitrag vorhanden ist.
  • Benutzer 2 fügt ein neues Foto hinzu.
  • Es gibt eine Verzögerung von 50 ms, bevor der neue Zyklus ausgelöst wird und die neuen Daten abgerufen werden.
  • Der neue Inhalt wird in den Bereich DOM geladen.

Dies scheint seltsam, wenn es in ein Beispiel aus der realen Welt übersetzt wird:

  • Benutzer 1 hält einen Stapel Bilder auf seinem Schreibtisch.
  • Er/sie geht jede Sekunde zum Fotografen und fragt, ob er/sie einen neuen hat.
  • Der Fotograf macht ein neues Foto.
  • In dieser Sekunde, wenn er/sie hereinkommt, kann sie das Bild aufnehmen und es auf den Stapel legen.

Meiner Meinung nach sollte die Lösung wie folgt sein:

  • Benutzer 1 hält einen Stapel Bilder auf seinem Schreibtisch.
  • Der Fotograf macht ein neues Bild.
  • Der Fotograf geht zum Stapel und legt ihn mit dem Rest zusammen.

Die PubNub-Lösung ist im Grunde die gleiche, diesmal läuft jedoch ein Praktikant zwischen den Parteien, um die Daten zu teilen.

Selbstverständlich sind beide Lösungen sehr energieaufwendig, da sie auch dann ausgelöst werden, wenn keine Daten geladen werden müssen.

Meines Wissens gibt es keine (logische) Erklärung, warum diese Art der Implementierung in fast jeder Echtzeitanwendung verwendet wird.

110
dennis

Pushing funktioniert gut für 1 oder eine begrenzte Anzahl von Benutzern.

Ändern Sie nun das Szenario mit einem Fotografen und 1000 Benutzern, die alle eine Kopie des Bildes wünschen. Der Fotograf muss zu 1000 Haufen laufen. Einige von ihnen befinden sich möglicherweise in einem verschlossenen Büro oder sind über den gesamten Boden verteilt. Oder ihr Benutzer im Urlaub und im Moment nicht an neuen Bildern interessiert.

Der Fotograf wäre die ganze Zeit damit beschäftigt, zu Fuß zu gehen und keine neuen Bilder zu machen.

Grundsätzlich gilt: Ein Pull/Poll-Modell lässt sich besser auf viele unzuverlässige Leser mit losen Echtzeitanforderungen skalieren (wenn ein Bild 10 Sekunden später benötigt, um auf einem Stapel anzukommen, worauf kommt es an).

Trotzdem ist ein Push-Modell in vielen Situationen immer noch besser. Wenn Sie eine geringe Latenz benötigen (Sie benötigen das neue Foto 5 Sekunden nach der Aufnahme) oder Aktualisierungen selten sind und häufig und vorhersehbar angefordert werden (fragen Sie den Fotografen alle 10 Sekunden, wenn er täglich ein neues Bild erstellt), ist das Ziehen unangemessen. Es hängt davon ab, was Sie versuchen zu tun. NASDAQ: Push. Wetterdienst: ziehen. Hochzeitsfotograf: wahrscheinlich ziehen. Nachrichtenfotoagentur: wahrscheinlich Push.

180
ptyx

Ich bin wirklich überrascht, dass nur eine Person WebSockets erwähnt hat. Unterstützung ist in praktisch jedem gängigen Browser implementiert .

Tatsächlich verwendet PubNub sie. Für Ihre Anwendung würde der Browser wahrscheinlich einen Socket abonnieren, der gesendet wird, sobald ein neues Foto verfügbar ist. Der Socket würde das Foto wohlgemerkt nicht senden, sondern nur einen Link, damit der Browser es asynchron herunterladen kann.

Stellen Sie sich in Ihrem Beispiel Folgendes vor:

  1. Benutzer teilen dem Fotografen mit, dass er über alle zukünftigen Fotos informiert werden möchte
  2. Der Fotograf sagt über den Lautsprecher, dass ein neues Foto verfügbar ist
  3. Der Benutzer bittet den Fotografen um ein Foto

Dies ähnelt in etwa Ihrer ursprünglichen Beispiellösung. Es ist effizienter als das Abrufen, da der Client keine Daten an den Server senden muss (außer vielleicht Herzschlag .)

Wie andere bereits erwähnt haben, gibt es auch andere Methoden, die besser sind als einfache Abfragen, die in älteren Browsern funktionieren ( longpolling, et al. .)

106
korylprince

Manchmal ist gut genug gut genug.

Von allen möglichen Möglichkeiten zur Implementierung eines "Echtzeit" -Kommunikationsprozesses ist die Abfrage möglicherweise die einfachste. Das Abrufen kann effektiv verwendet werden, wenn das Abfrageintervall relativ lang ist (d. H. Sekunden, Minuten oder Stunden statt sofort) und die durch Überprüfen der Verbindung oder Ressource verbrauchten Taktzyklen keine Rolle spielen.

42
Robert Harvey

Das HTTP-Protokoll ist dahingehend eingeschränkt, dass der Client derjenige sein muss, der die Anforderung initiiert. Der Server kann nicht mit dem Client kommunizieren, es sei denn, er antwortet auf die Anfrage eines Clients.

Fügen Sie die folgende Einschränkung hinzu, um Ihr Beispiel aus der realen Welt anzupassen:

  • Benutzer 2 kann NUR auf die Fragen von Benutzer 1 mit einer einzigen Satzantwort antworten, wonach Benutzer 1 gehen muss. Benutzer 2 hat keine andere Art der Kommunikation.

Wie würden Sie es mit dieser neuen Zurückhaltung anders machen als mit Umfragen?

31
riwalk

Warum werden Umfragen akzeptiert? Denn in Wirklichkeit ist jede Lösung ein Low-Level-Polling!

Wenn der Server Sie aktualisieren soll, sobald neue Bilder verfügbar sind, muss er normalerweise eine Verbindung zu Ihnen haben - da sich die IP-Adressen häufig ändern und Sie nie wissen, ob jemand nicht mehr interessiert ist, muss der Client eine Form von senden Keep-Alive-Signal, zum Beispiel "Ich bin immer noch hier, ich bin nicht offline"

Alle zustandsbehafteten Verbindungen (z. B. TCP/IP) funktionieren gleich, da Sie nur einzelne Datenpakete über das Internet senden können. Sie wissen nie, ob die andere Partei noch da ist.

Jedes Protokoll hat also eine Zeitüberschreitung. Wenn eine Entität nicht innerhalb von X Sekunden antwortet, wird angenommen, dass sie tot ist. Selbst wenn Sie nur eine offene Verbindung zwischen Server und Client haben, ohne Daten zu senden, müssen Server und Client reguläre Keep-Alive-Pakete senden (dies wird auf niedriger Ebene behandelt, wenn Sie eine Verbindung zwischen ihnen herstellen) - und wie ist das? das am Ende anders als bei der Umfrage?

Der beste Ansatz wäre also wahrscheinlich Longpolling:

Der Client sendet sofort nach dem Laden der Site eine Anfrage (z. B. dem Fotografen "Sagen Sie mir, ob neue Bilder vorhanden sind"), der Server antwortet jedoch nicht, wenn keine neuen Bilder vorhanden sind. Sobald die Anforderung abgelaufen ist, fragt der Client erneut.

Wenn der Server jetzt neue Bilder hat, kann er sofort alle Clients beantworten, die für neue Bilder anstehen. Ihre Reaktionszeit nach einem neuen Bild ist also noch kürzer als bei Push, da der Client immer noch in einer offenen Verbindung auf eine Antwort wartet und Sie keine Verbindung zum Client aufbauen müssen. Und die Abfrageanfragen vom Client sind nicht viel mehr Verkehr als eine ständige Verbindung zwischen Client und Server für eine Antwort!

13
Falco

Ein Vorteil der Abfrage besteht darin, dass der Schaden begrenzt wird, der verursacht werden kann, wenn eine Nachricht verloren geht oder der Status von etwas fehlerhaft wird. Wenn X Y alle fünf Sekunden nach seinem Status fragt, führt der Verlust einer Anfrage oder Antwort lediglich dazu, dass die Informationen von X nicht fünf, sondern zehn Sekunden veraltet sind. Wenn Y neu gestartet wird, kann X dies beim nächsten Mal herausfinden Zeit Y kann auf eine der Nachrichten von X antworten. Wenn X neu gestartet wird, wird es möglicherweise nie die Mühe machen, Y danach um etwas zu bitten, aber wer den Status von X beobachtet, sollte erkennen, dass es neu gestartet wurde.

Wenn sich X anstelle von Y auf Y verlassen hat, um Y zu informieren, wann immer sich sein Status ändert, dann hat sich der Status von Y geändert und eine Nachricht an X gesendet, aber aus welchem ​​Grund auch immer diese Nachricht nicht empfangen wurde, wird X möglicherweise nie auf die Änderung aufmerksam . Ebenso, wenn Y neu gestartet wird und keinen Grund hat, X eine Nachricht über irgendetwas zu senden.

In einigen Fällen kann es hilfreich sein, wenn X anfordert, dass Y autonom Nachrichten mit seinem Status sendet, entweder periodisch oder wenn es sich ändert, und nur dann eine X-Abfrage durchführt, wenn es zu lange dauert, ohne etwas von Y zu hören. Ein solches Design kann das beseitigen X muss die meisten seiner Nachrichten senden (normalerweise sollte X Y zumindest gelegentlich darüber informieren, dass es weiterhin am Empfang von Nachrichten interessiert ist, und Y sollte das Senden von Nachrichten beenden, wenn es zu lange dauert, ohne dass ein Hinweis auf Interesse erfolgt). Ein solches Design würde jedoch erfordern, dass Y dauerhaft Informationen über X beibehält, anstatt einfach eine Antwort an denjenigen senden zu können, der sie abgefragt hat, und dann sofort vergisst, wer das ist. Wenn Y ein eingebettetes System ist, kann eine solche Vereinfachung dazu beitragen, den Speicherbedarf ausreichend zu reduzieren, um die Verwendung eines kleineren und billigeren Controllers zu ermöglichen.

Das Abrufen kann einen zusätzlichen Vorteil haben, wenn ein möglicherweise unzuverlässiges Kommunikationsmedium (z. B. UDP oder Funk) verwendet wird: Es kann die Notwendigkeit von Bestätigungen auf Verbindungsebene weitgehend eliminieren. Wenn X Y eine Statusanforderung Q sendet, Y mit einem Statusbericht R antwortet und X R hört, muss X keine Bestätigung der Verbindungsschicht hören, damit Q weiß, dass sie empfangen wurde. Umgekehrt muss Y, sobald es R sendet, nicht wissen oder sich darum kümmern, ob X es empfangen hat. Wenn X eine Statusanforderung sendet und keine Antwort erhält, kann es eine andere senden. Wenn Y einen Bericht sendet und X ihn nicht hört, sendet X eine weitere Anfrage. Wenn jede Anfrage einmal ausgeht und entweder eine Antwort liefert oder nicht, muss keine Partei wissen oder sich darum kümmern, ob eine bestimmte Nachricht empfangen wurde. Da das Senden einer Bestätigung fast so viel Bandbreite beansprucht wie eine Statusanforderung oder ein Statusbericht, kostet die Verwendung eines Roundtrips von Anforderungsberichten nicht viel mehr als ein unaufgeforderter Bericht und eine Bestätigung. Wenn X einige Anforderungen sendet, ohne Antworten zu erhalten, muss es in einigen dynamisch gerouteten Netzwerken möglicherweise Bestätigungen auf Verbindungsebene aktivieren (und in seiner Anforderung Y auffordern, dies ebenfalls zu tun), damit der zugrunde liegende Protokollstapel das Übermittlungsproblem erkennen und suchen kann eine neue Route, aber wenn die Dinge funktionieren, ist ein Anforderungsberichtsmodell effizienter als die Verwendung von Bestätigungen auf Verbindungsebene.

9
supercat

Aus irgendeinem Grund scheinen heutzutage alle jüngeren Webentwickler die Lehren aus der Vergangenheit vergessen zu haben und warum sich einige Dinge so entwickelt haben, wie sie es getan haben.

  1. Bandbreite war ein Problem
  2. Die Verbindung kann unterbrochen sein.
  3. Browser hatten nicht so viel Rechenleistung
  4. Es gab andere Methoden für den Zugriff auf Inhalte. Das Web ist nicht w3.

Angesichts dieser Einschränkungen verfügen Sie möglicherweise nicht über eine konstante bidirektionale Kommunikation. Wenn Sie sich das OSI-Modell ansehen, werden Sie feststellen, dass die meisten Überlegungen dazu dienen, die Persistenz mit der zugrunde liegenden Verbindung zu entkoppeln.

Vor diesem Hintergrund ist eine Abfragemethode zum Abrufen von Informationen eine hervorragende Möglichkeit, die Bandbreite und die Berechnung auf der Clientseite zu reduzieren. Der Aufstieg von Push ist größtenteils nur der Client, der ständige Abfragen oder Web-Sockets durchführt. Persönlich, wenn ich alle anderen da draußen wäre, würde ich die Regelmäßigkeit der Abfrage als Mittel zur Verkehrsanalyse schätzen, bei der eine verspätete GET/POST-Anfrage einen Mann in einer mittleren Situation signalisieren würde.

1
guestaccount

Die Frage ist, die Anzahl unnötiger Umfragen gegen die Anzahl unnötiger Pushs abzuwägen.

Wenn Sie abstimmen:

  • Sie erhalten in diesem Moment eine Antwort. Gut, wenn Sie nur gelegentlich fragen oder gerade einen Datensatz benötigen.
  • Möglicherweise erhalten Sie die Antwort "Kein Inhalt", wodurch die Leitung sinnlos belastet wird.
  • Sie belasten die Leitung nur, wenn Sie abfragen, aber immer, wenn Sie abfragen.

Wenn Sie drücken:

  • Sie liefern die Antwort sofort, wenn sie verfügbar ist, was eine sofortige Verarbeitung auf der Client-Seite ermöglicht.
  • Sie können Daten an Clients liefern, die nicht an diesen Daten interessiert sind, was zu einer sinnlosen Belastung der Leitung führt.
  • Sie belasten die Leitung jedes Mal, wenn neue Daten vorliegen, jedoch nur, wenn neue Daten vorhanden sind.

Es gibt verschiedene Lösungen für den Umgang mit den verschiedenen Szenarien und ihren Nachteilen, z. B. eine Mindestzeit zwischen Abstimmungen, Nur-Umfrage-Proxys, um das Hauptsystem zu entlasten, oder - für die Pushs - eine Regelung zur Registrierung und Festlegung die gewünschten Daten, gefolgt von der Aufhebung der Registrierung beim Abmelden. Welches am besten passt, kann man im Allgemeinen nicht sagen, es hängt vom System ab.

In Ihrem Beispiel ist Polling nicht die effizienteste, sondern die praktischste Lösung. Es ist sehr einfach, ein Abfragesystem in JavaScript zu schreiben, und es ist auch auf der Bereitstellungsseite sehr einfach zu implementieren. Ein Server, der für die Bereitstellung von Bilddaten erstellt wurde, sollte in der Lage sein, die zusätzlichen Anforderungen zu verarbeiten. Andernfalls kann er linear skaliert werden, da die Daten größtenteils statisch sind und daher leicht zwischengespeichert werden können.

Eine Push-Methode, die ein Anmelden, eine Beschreibung der gewünschten Daten und schließlich ein Abmelden implementiert, wäre am effizientesten, ist jedoch wahrscheinlich zu komplex für den durchschnittlichen "Script-Kiddy" und muss sich mit der Frage befassen: Was ist, wenn der Benutzer fährt einfach den Browser herunter und die Abmeldung kann nicht durchgeführt werden?

Vielleicht ist es besser, mehr Benutzer zu haben (da der Zugriff einfach ist), als etwas Geld auf einem anderen Cache-Server zu sparen?

1
TwoThe