Dieser Artikel wurde maschinell übersetzt.

Schneide

Langes Abrufen (Long Polling) und SignalR

Dino Esposito

 

Dino EspositoWir bauen immer mehr anspruchsvollen Webanwendungen über ein Protokoll, die paradoxerweise wurde konzipiert und entwickelt für viel einfacheren Formen der Interaktion. HTTP verfügt über keine integrierte Unterstützung für staatliche oder auch Sicherheit. Die Grundannahme ist, dass der Client eine Anforderung und der Webserver eine Antwort sendet. In der Summe bedeutet, dass kein Wunsch, keine Antwort.

Angesichts der aktuellen Marktdurchdringung des Web und der weiten Verbreitung von Web-Lösungen, ist die Säulen des Web (HTTP, HTML, JavaScript) zu ändern, nicht in Frage. Aber sollten wir darüber nachdenken, einige der diese Säulen zu verbessern? Natürlich. Moderne Anwendungen haben spezifische Anforderungen, die Web-Protokolle und Sprachen bis an ihre Grenze push — oder darüber hinaus.

In den letzten Ausgaben dieser Rubrik erörtert eine handgefertigte Implementierung eines Mechanismus, der den Server abfragt und meldet Änderungen an den Client. Im vergangenen Monat ich implementiert die gleiche Idee mit einer neuen Bibliothek — SignalR. Ich werde jetzt bieten einen kurzen Überblick über die Techniken und eine Zusammenfassung der Optionen, die Sie heute haben. Ich werde SignalR im Rampenlicht und betrachten Sie deren Umsetzung — und einige seiner Magie.

Abruf-Überlegungen

Da die HTTP-Anforderung/Antwort-Einschränkung, ist Abruf die einzige Möglichkeit zum Einrichten von live-Kommunikation zwischen einem Client und einem Webserver. Der Client legt Anforderungen an ihrer Bequemlichkeit und der Server antwortet fleißig. Der Schlüssel zur Bewertung der Wirksamkeit von Polling ist die tatsächliche Bedeutung, die Sie zuweisen, der Ausdruck "auf seine Bequemlichkeit." Es gibt immer eine Clientanforderung das Herzstück jeder Lösung basierend auf Abruf. Die Anforderung steht, bis der Server geantwortet hat. Jede ausstehende Anforderung verbraucht eine Browser-Verbindung und, noch wichtiger ist, greift einen Serverthread, machen diese wertvolle Ressource für andere Anfragen nicht mehr verfügbar. Kurz gesagt, bauen allzu häufigen Anfragen Druck auf dem Webserver.

Aber nicht die Fähigkeit des Servers, einer wachsenden Anzahl von Anfragen über die Idee der Skalierbarkeit behandeln? In der Tat Abfrage erstellt keine neuen Skalierbarkeit Bedenken, aber es addiert eine beträchtliche Anzahl von neuen Anforderungen an den Server, der berücksichtigt werden muss um sicherzustellen, dass einen skalierbaren und leistungsstarke Server. Mal sehen, wie wir Abruf implementiert werden können.

AJAX-Polling

Meine Dezember 2011 (msdn.microsoft.com/magazine/hh580729) und Januar 2012 (msdn.microsoft.com/magazine/hh708746) Spalten, legte ich einen Rahmen für die Steuerung des Fortschritts der einen remote-Betrieb. Das gesamte Framework basiert auf AJAX-Aufrufe. Zunächst ruft der Client den Endpunkt ein Servers auf einen möglicherweise langwierigen Task starten; als nächstes richtet es einen Timer gleichzeitige Anrufe an einen anderen Endpunkt alle 500 Millisekunden platziert. Der Server-Task seine Arbeit erledigt, aktualisiert es einen bekannten Speicherort. Der Serverendpunkt, der in regelmäßigen Abständen einfach überprüft, ob Daten in diesem Speicherort aufgerufen und gibt Inhalte findet es an den Client.

Dieses Muster AJAX-Abfrage funktioniert wunderbar und ist weit verbreitet in vielen Industrie-Szenarien eingesetzt. Die meisten Websites, die Nachrichten Updates zur Verfügung gestellt oder live Resultate folgen diesem Muster. In meinen Artikeln angepasst ich einfach das Muster auf das spezifische Szenario der Überwachung der remote-Betrieb.

Am Ende ist das Problem mit AJAX Abfrage herauszufinden, die richtige Aktualisierungsintervall — eine,, eine gute Balance zwischen Druck auf dem Server und Genauigkeit der Informationen darstellt, für Benutzer gemeldet. Eine effektive Lösung für AJAX-Abfrage gibt eine konkrete Bedeutung "an den Client Bequemlichkeit" in Senden von Anforderungen.

Lange Polling

Vor AJAX verwendet Entwickler der Meta Refresh-HTML-Tag Browser eine Seite aktualisieren anweisen jede angegebene Anzahl von Sekunden. Mit AJAX Abfrage erzielen Sie die gleiche Sache, aber eine viel glattere Weg.

Für eine wachsende Zahl von Anwendungen reicht jedoch diese Form von Polling. AJAX Abfrage führt fast zwangsläufig eine Verzögerung zwischen dem Auftreten eines Ereignisses auf dem Server und die Benachrichtigung über das Ereignis an den Client. Durch die Häufigkeit der Aktualisierungen optimieren, trainieren Sie gute Lösungen, doch AJAX Abfrage kann nicht liefern, dass kontinuierliche Verbindung, die viele (vor allem soziale) Anwendungen scheinen heute brauchen.

Die Lösung scheint in diesen Tagen lang abrufen. Seltsamerweise, wenn AJAX vor Jahren entstanden, intelligenter AJAX Abfrage ersetzt lange abrufen, da Letzterer nicht sehr effektiv über das Internet war. Lange abrufen ist über die gleichen Dinge, die Sie in einem Szenario mit desktop über das Internet tun. Mit langen Abruf, der Client stellt die Anfrage und der Server antwortet nicht, bis es hat Informationen zurückgeben. Der WebClient hält eine ausstehende Verbindung, die geschlossen wird, nur wenn eine gültige Antwort zurückgegeben werden kann. Das ist genau das, was Sie heute wollen – außer dass es das Potenzial hat für eine Verlangsamung des Web-Servers.

Lange Abfragen stellt eine kleinere Anzahl von Anforderungen an den Server mit AJAX Abfrage verglichen, aber jede Anforderung könnte viel länger dauern. Im Laufe der Zeit kann dies schädlich für die Gesundheit des Web-Servers, da hält es Server-Threads beschäftigt, bis eine Antwort generiert werden kann. Mit weniger Worker-Threads zu einem bestimmten Zeitpunkt zur Verfügung der Webserver zwangsläufig langsamer im reagieren auf andere Anforderungen es empfängt. Um wirksam zu sein, braucht lange Abfragen, einige ernsthafte Umsetzung Arbeit und Erweiterte Multithread und parallele Programmierkenntnisse. Also, für Jahre, lange Abfragen war nicht wirklich eine Option, aber es spielte keine Rolle, da gab es keine Nachfrage für ständige Konnektivität.

Heute, mit der Task Parallel Library in Microsoft.NET Framework 4 und anderen Einrichtungen in ASP.NET zum Erstellen von asynchroner HTTP-Handlers, lange Abfragen ist eine praktikable Option geworden. Insgesamt ist das Kalligraphieren eines Long-Polling-Rahmens noch härter als einen entsprechenden AJAX-Polling-Rahmen. Sie benötigen eine gut konzipierte Serverumgebung, die den Webserver Steuern nicht und einer Clientumgebung, die lange Abfragen unterstützen kann. Lange Abfragen, bezieht sich tatsächlich auf eine Makro-Client/Server-Betrieb, die über das Web und unbedingt über eine Reihe von klassischen HTTP-Anforderung/Antwort-Pakete entwickelt. Der Client muss intelligent genug, um eine sofortige neue Anforderung wiederholen, bis der Makro-Vorgang beendet wird. Ich werde später darauf zurück.

SignalR zur Rettung

SignalR ist ein Microsoft-Framework speziell für Echtzeit-Client/Server-Kommunikation zu erleichtern. Es bietet eine wirksame Umsetzung von Long polling, die keinen tiefen Einfluss auf dem Server haben, und gleichzeitig wird sichergestellt, dass Clients über das geschehen aus der Ferne auf entsprechend aktualisiert werden. Abbildung 1zeigt einen Auszug aus der Code ich in meinem letzten Artikel vorgestellt. Die BookingHub-Klasse ist die Methode, die Sie aufrufen vom Web-Browser, startet den Makro "den Flug buchen."

Abbildung 1 SignalR Klasse, die eine Multistep-Operation führt

public class BookingHub : Hub
{
  public void BookFlight(String from, String to)
  {
    // Book first leg
    Clients.displayMessage(
      String.Format("Booking flight: {0}-{1} ...", from, to));
    BookFlightInternal(from, to);
    // Book return
    Clients.displayMessage(
      String.Format("Booking flight: {0}-{1} ...", to, from));
    BookFlightInternal(to, from);
    // Book return
    Clients.displayMessage("Charging credit card ...");
    ChargeCreditCardInternal();
    // Some return value
    Clients.displayMessage("Flight booked successfully.");
  }
}

Dies ist eindeutig ein multistep Vorgang, und für jeden Schritt die Klasse sendet eine Benachrichtigung an den Client. Wie viele HTTP-Anforderungen sind beteiligt? Werfen Sie einen Blick mit Fiddler (siehe Abbildung 2).

The Full Stack of HTTP Requests for the Flight-Booking Operation
Abbildung 2 die vollständige Stapel von HTTP-Anforderungen für die Flugbuchung Operation

Innerhalb einer SignalR Operation

Die erste Anforderung wird ausgelöst, wenn Sie den Methode Start, von der Clientseite aufrufen; Dies identifiziert den Client zum Back-End SignalR. Es sei darauf hingewiesen, dass die erste Anforderung eine spezielle Aushandlungsanforderung ist. AJAX wird immer unabhängig von der endgültige Transport für die Verbindung ausgehandelt sein. Jede SignalR Web-Seite enthält Code wie den folgenden, die ausgeführt wird, wenn eine Seite geladen:

$(function () {
  var bookingHub = $.connection.bookingHub;
  bookingHub.start();
}

Auf diese Weise erklärt die Seite seine Absicht, eine Verbindung zu der Dienste des serverseitigen BookingHub-Objekts aufrufen, öffnen. Beachten Sie, dass es SignalR ist, die die Magie ein Clientobjekts entsprechend der öffentlichen Schnittstelle des serverseitigen Hub-Objekts zu erstellen. Der Name des JavaScript-Objekts mit dem Namen des Server-Objekts übereinstimmt. Jedoch können Sie das HubName-Attribut verwenden, um die Bezeichnung auf dem Client zu ändern:

[HubName("booking")]
public class BookingHub : Hub
{
  ...
}

Die Start-Anforderung gibt eine Client-ID, die der Client zusammen mit jedem aufeinander folgenden Anforderungen übergeben werden.

{"Url":"/signalr","connectionId":"2a119962-edf7-4a97-954b-e74f2f1d27a9"}

Als Nächstes legt die Client-Bibliothek eine weitere Anforderung für Verbindung. Dies ist die "verbinden", was die OnConnect-Ereignis ausgelöst wird, für die Verbindung auf dem Server führt. Abbildung 3 zeigt ein paar der Connect-Anfragen.

Reiterating Connection Requests
Abbildung 3 Bekräftigung Verbindungsanforderungen

Die ersten zwei Minuten abgeschlossen; Das zweite ist noch ausstehend. Dies ist die Essenz von Long polling – der Client hat einen kontinuierlich offene Kanal mit dem Server. Server Timeout der Anforderung nach zwei Minuten wenn keine Aktion auf dem Server, die erfordert ausgeführt wird, sendet Daten an den Client zurück. Bei der Flugbuchung Anwendung UI gibt es eine Schaltfläche, die der Benutzer klicken kann, starten Sie den Flug buchen. Wenn der Benutzer auf die Schaltfläche klickt, führt den folgenden Code:

bookingHub.bookFlight("fco", "jfk");

Wenn Sie die Beispielanwendung von Artikel des letzten Monats erstellt haben, sollten Sie diesen Code hinzu den Click-Ereignishandler der Seitenschaltfläche verknüpft haben.

Das BookingHub-Objekt gehört zu einem Skript, das SignalR über die URL Signalr/Hubs downloadet wie in gezeigt Abbildung 3. BookingHub ist ein einfachen Proxyobjekt, das die Komplexität der Umsetzung einer Long-Polling-Musters verbirgt. Durch Klicken auf die Schaltfläche löst eine neue Anforderung an den Server, in dem die Client-ID eingebettet ist. Wenn der Server einen Anruf von einem Client, die eine ausstehende Forderung hat empfängt, endet die ausstehende Forderung und beginnt die neue Anforderung verarbeitet, wie in Abbildung 4.

A Multistep Operation Is Taking Place
Abbildung 4 Multistep Operation stattfindet

Abbildung 4 zeigt eine ausstehende Anforderung (Signalr/senden), zwei abgeschlossene Anforderungen und eine weitere ausstehende Anforderung. Signalr/Sendeanforderung ist der ursprüngliche Aufruf der Makro-Vorgang für die Buchung des Fluges, deren Quellcode in erscheint Abbildung 1.

Der Code in Abbildung 1 Ruft den Client in den verschiedenen Stadien zu es Fortschritte, etwa so:

Clients.displayMessage(...);

Zur gleichen Zeit, die eine Anforderung für Signalr/senden platziert wird, beginnt eine weitere Anforderung auf Benachrichtigungen warten.Diese Anforderung wartet, bis es gibt Daten zurück senden.Jeder Aufruf an Clients im Servercode schließt die Anforderung für die Benachrichtigung und löst sofort eine vom Client, also die Reihenfolge, in Abbildung 4 bedeutet, dass zwei Schritte abgeschlossen wurden und zwei Statusmeldungen vom Client empfangen wurden.Der Server ist nun damit beschäftigt, den dritten Schritt zu erreichen.Ende des Codes in Abbildung 1, alle Anforderungen im Abbildung 4 abgeschlossen haben und die Situation wird wieder eine ähnlich, was, in gezeigt wird Abbildung 2.

Darüber hinaus lange Polling

Vergleicht man das Verhalten von langen abrufen, wie im SignalR mit den Schritten umgesetzt ich gemäß meiner Artikel über AJAX Abfrage, Sie sollte ein gemeinsames Muster erkennen — die Statusanzeige-Muster.AJAX polling und langen Abfragen sind zwei unterschiedliche Implementierungen des gleichen Musters.Welche effektiver ist, hängt von der Konfiguration des Webservers und Anforderungen der Anwendung.Es ist Ihr Anruf.In jedem Fall, wenn Sie für lange Abfrage entscheiden, benötigen Sie SignalR oder eine analoge Bibliothek.Wenn Sie Ihr eigenes Framework erstellen möchten, schlage ich vor, Sie entscheiden sich für die zahlreichen-aber-Quick Aufrufe von AJAX Polling im Vergleich zu den weniger-aber mehr Anrufe von Long polling.

Aufbau eines wirksamen Long-Polling-Rahmens kann schwierig sein.Mit AJAX Abfrage Sie wahrscheinlich nicht ständige Konnektivität, aber auch nicht riskieren Sie verlangsamen den Server.In diesem Sinne ich wahrscheinlich nicht gehen herum und aktualisieren alle Echtzeit-Web-Server, die ich kümmern, SignalR.Sobald SignalR freigegeben wird, nicht jedoch aus irgendeinem Grund nicht zu verwenden für neue Anwendungen angezeigt.

Schließlich ist es erwähnenswert, dass SignalR jetzt anderen übergeordneten Transporte neben langen Abrufintervall unterstützt.In der aktuellen Quelle finden Sie auch Unterstützung für WebSockets auf Windows 8 Server; Server gesendeten Ereignisse auf Chrome, Firefox, Opera und Safari; und Rahmen für immer im InternetExplorer.Die Bibliothek am Anfang der Liste beginnt und hält fallen zurück, bis ein unterstützter Transport gefunden wird.Also, wird am Ende lange Abfragen tatsächlich nur selten in den meisten Fällen verwendet werden.

Dino Esposito ist der Autor von "Programming ASP.NET 4 "(Microsoft Press, 2011) und"Programmieren von ASP.NET MVC 3 "(Microsoft Press, 2010) und Mitautor von"Microsoft."NET: Planung Anwendungen für Unternehmen"(Microsoft Press, 2008).Mit Sitz in Italien, ist Esposito ein gefragter Referent bei Branchenveranstaltungen weltweit.Folgen Sie ihm auf Twitter bei Twitter.com/despos.

Unser Dank gilt dem folgenden technischen Experten für die Durchsicht dieses Artikels: Damian Edwards