Reiten auf dem Internet Zug aufspringen

Das Versenden von großen Seiten von HTML ist nicht mehr ein Problem ist jetzt, dass wir in der Lage, Druckseiten zu senden!

Nach zwei Wochen non-stop-Programmierung, ist die Web-Anwendung bereit und getestet. Alles ist A-OK und das Lächeln auf den Gesichtern der Ihre Kunden auf eine seltsame Weise von remember "Jaws". Bis auf eine Sache. Jemand in den Rücken schüchtern fragte, ob etwas getan werden könnte, zur Beschleunigung der Suchergebnisseite, die so viel Text enthält werden. In diesem Moment wissen Sie, dass Sie eine vollständige Kopie des Antrags mit Ihnen gebracht haben, anstatt über der Linie demonstrieren 33.6kb Modem zu arbeiten.

Aber nicht alles verloren ist. Es gibt Möglichkeiten, die Menge der Daten, die an den Client gesendet werden muss, zu reduzieren, und ich spreche nicht mit weniger Informationen übertragen, sondern vielmehr, um komprimierte Daten zu senden. Klingt interessant? Lesen Sie weiter und lernen.

AssumptionsSince frivol Dieser Artikel beschreibt die Funktionen und Techniken, die der Komplexität einer Web-Anwendung hinzufügen wird, wird davon ausgegangen, dass Sie bereits wissen, wie man eine Web-Anwendung, insbesondere eine ISAPI-DLL zu erstellen, und als solche die Anwendung funktioniert. Als solche überspringe ich einige Details, aber ich versichere Ihnen - Ich werde mit all den Optionen und der speziell für die Techniken, die wir hier gelten benötigte Code stehen.

In diesem Sinne sind wir ein wenig mehr "Saft aus Ihren guten alten Internet-Leitung zu quetschen.

Wie wird die Magie gemacht? Wie ist es möglich könnte man fragen? Sie haben wahrscheinlich bei ein oder andere Mal heruntergeladen komprimierte Datei, nur um herauszufinden, dass Ihr Browser irgendwie interpretiert die Daten entweder als eine Web-Seite oder Text und Anzeige dieser auf dem Bildschirm in seiner ganzen Pracht. Es ist kein schönes Bild, um es gelinde auszudrücken. Wenn Sie die Daten, bevor Sie an den Kunden schicken, komprimiert waren, nicht als seltsam erscheinen dann? Nicht wirklich, nur sicherstellen, dass der Kunde weiß, dass er in einer anderen Art und Weise zu verwalten.

Das Geheimnis innerhalb der Daten sendet der Client an den Web-Server und in den Daten der Web-Server antwortet mit versteckt. Es heißt Inhaltscodierung. Kurz gesagt, ist es möglich, die Daten zu kodieren ergibt Anwendungen für den Kunden, und die einzige Vorsichtsmaßnahme ist, um sicherzustellen, dass der Kunde weiß, wie die gewählten Daten-Encoding-Format umgehen. Dies wiederum ist einfach, weil der Kunde sagt Ihnen, welche Formate es verarbeiten kann, wenn Sie die Anfrage an den Server zu senden.

Also, was es läuft darauf hinaus, dass Sie die folgenden Schritte, wenn Sie kodieren die Daten an den Client zurückgegeben werden soll:

  1. Prüfen Sie, ob der Kunde in der Lage ist, die Art der Verschlüsselung, die Sie verwenden möchten, behandelt
  2. Kodiert die Daten in Ihrem bevorzugten Format
  3. Zurück neuen codierten Daten und sagen dem Kunden, was von Ihnen in codierte
  4. Welches Format soll ich verwenden? Wir sind daran interessiert, Komprimieren der Daten zurück an den Client. Es ist eine Art der Codierung, die speziell für diesen Zweck, und sein Name ist "entleert". Die bei der Codierung verwendeten Art Kompressionsalgorithmus entspricht dem Deflate-Algorithmus, der die Kompressionsbibliothek zlib implementiert. Sie können mehr über diese Bibliothek hier lesen: http://www.cdrom.com/pub/infozip/zlib oder überprüfen Sie die RFC beschreibt den Algorithmus und Binär-Format hier: http://www.funet.fi/ pub/doc /rfc/rfc1950.txt.

    Obwohl Sie vielleicht denken, dass Sie bereits über die benötigten Dateien, um die Kompressionsbibliothek zlib nutzen - Sie nicht! Zumindest nicht genau. Obwohl die Installations-CD Delphi kommt mit einer Kopie der Kompressionsbibliothek zlib, in Form von vorkompilierte Objektdateien und einige Datei-Import, versteckt die Details, die wir haben, zu bedienen. Mehr dazu später, aber jetzt lassen Sie s genügt zu sagen, dass wir eine bessere Schnittstelle für die Bibliothek und aus diesem Grund wählte ich zu meiner Einheit Import Zlib und einen Link zu vorkompilierte DLL downloaden geben: http: // www. winimage.com/zLibDll/.

    In Bezug auf die "Ablass 'Codierungstyp wird nur angezeigt, Microsoft Internet Explorer in der Handhabung und erst später wieder Versionen (Version 4 und höher Griffe nicht, alles, was darunter ist nicht sicher). Das ist keine große Sache, aber da die anderen Browser wie Netscape, nicht sagen, sie in der Lage, die Art der Komprimierung Codierung handhaben sind. In diesem Fall unsere Web-Anwendung einfach nicht zurück mit den komprimierten Daten sein. Der einzige Unterschied wäre ein wenig mehr Zeit, um die Daten zu dem Client herunterzuladen. Das ist nicht schlechter als das, was wir heute haben, so dass ich denke, dass wir damit leben können.

    Ok, ich habe die Datei, was nun? Jetzt ist die Zeit, sich auf die blutigen Details zu erhalten. Lassen Sie uns gehen, um einen guten Start mit der Erstellung eines neuen Projekts in Delphi 5 ISAPI und sehen, wo es uns braucht. Sie sollten das Laufwerk importieren herunter an diesem Projekt hinzufügen. Die DLL kann so schnell heruntergeladen werden, wie es in dem Verzeichnis C gesetzt wird: \ WINNT \ System32 (oder dem entsprechenden Verzeichnis) oder im selben Verzeichnis wie einer Web-Anwendung.

    Nach der Erstellung des neuen Projekts, fügen Sie eine Aktion, um sie, buchstäblich. Fügen Sie eine Aktion, die das Web-Formular und erstellen Sie einen leeren Ereignishandler für sie. Machen Sie die Aktion die Standardaktion, und da dies nur eine Demo-Anwendung, um unsere neue Art der Rückgabe von Daten versuchen.

    Jetzt haben wir ein Event-Handler auf eine leere Aktion, um zu gehen? S einige Code hinzufügen, um es zu machen, es zu tun, was wir brauchen. Ich zeige Ihnen das komplette Event-Handler und dann werde ich durch die Details zu gehen.

    Verfahren TWebModule1.WebModule1WebActionItem1Action (Sender: TObject; Anfrage: TWebRequest; Antwort: TWebResponse; var
    behandelt: Boolean);
    var
    PlaintextStream: TStream;
    CompressedStream: TStream;
    Start
    wenn (ClientAcceptsDeflate (Request)) und dann
    Start
    // 1 Erstellen Sie zunächst eine temporäre Strom mit den Daten, die zurückgegeben werden
    PlaintextStream: = TStringStream.Create ("Dieser Text wird komprimiert ');
    versuchen
    // 2 Zweitens schaffen temporäre Fluss für unsere Druckdaten
    CompressedStream: = TMemoryStream.Create;
    versuchen
    // 3 Jetzt komprimieren den Fluss ...
    zLibCompressStream (PlaintextStream, CompressedStream);

    // ... Es gibt
    CompressedStream.Position: = 0;
    Response.ContentStream: = CompressedStream;
    außer
    FreeAndNil (CompressedStream);
    Aufzug;
    Ende; Versuchen // Ausnahme - zu vermeiden Speicherlecks
    endlich
    // 4 Schließlich ordnen temporäres Objekt
    FreeAndNil (PlaintextStream);
    Ende; Versuchen // schließlich - Objektfluss im Klartext zu zerstören
    Response.ContentType: 'text/plain' =;
    Response.ContentEncoding: = 'deflate';
    Response.StatusCode: = 200;
    behandelt: = True;
    Ende // Daten, wenn der Kunde akzeptiert Druck
    sonst beginnen
    Response.Content: = 'komprimierte';
    Response.ContentType: 'text/plain' =;
    Response.StatusCode: = 200;
    behandelt: = True;
    Ende; // Wenn der Client keine komprimierten Daten nicht akzeptieren,
    Ende; Verfahren // TWebModule1.WebModule1ActionItem1Action

    Die if-Anweisung hier prime bestimmt, ob der Client komprimierten Daten verarbeiten und sendet dann sowohl die Daten komprimiert oder unkomprimiert an den Kunden entsprechend. Die unkomprimierten Daten werden behandelt, wie Sie es immer geschafft haben, Daten in einer Web-Anwendung, so dass Sie nicht weiter zu diskutieren es nicht. Stattdessen werden wir den Schwerpunkt auf die Wenn-Dann-Teil der if-Anweisung, die komprimierten Daten verarbeitet. Sie haben wahrscheinlich bemerkt, dass wir mit zwei neuen Prozeduren/Funktionen hier, nämlich ClientAcceptsDeflate und zLibCompressStream. Ich werde durch diese später in diesem Artikel gehen.

    Unter der Annahme, dass wir ein Verfahren, das einen Strom als Eingabe erfordert erhalten, komprimiert die Daten von diesem Strom hält und schreibt die komprimierten Daten in einen Ausgabestrom, können wir die oben in dieser Weise gezeigt Code zu beschreiben:

    1. Erstellen Sie zunächst eine temporäre Strom alles enthält, die wir an den Client zurückgegeben werden sollen
    2. Zweitens, komprimieren die Daten und setzen die komprimierten Daten in einem neuen Fluss
    3. Diese neue Strömung, halten unsere Druckdaten, wir bringen Sie einfach an den Client
    4. Schließlich aufräumen unsere temporäre Objekte
    5. Sie können die entsprechenden Punkte von dieser Liste in den Kommentaren nummeriert Event-Handler oben finden. Es ist der Code ganz einfach, und sollte auch sein, da wir versteckten die blutigen Details in zwei Funktionen, die wir später diskutieren.

      Eine Sache zu beachten ist, dass wenn Sie die Eigenschaft des Response-Objekts, um unsere Contentantwortstream-bject zuweisen, hat das Eigentum an der Strömung. Sobald die Antwortdaten an den Kunden gesendet werden, Fluss uns freigegeben werden, so müssen wir sicherstellen, dass Sie nicht versehentlich selbst befreien. Im Falle einer Ausnahme, aber ich schlug vor, dass der Job drunter und drüber gegangen ist, und dann frei den Flow vor propagieren eher die Ausnahme als die Spitze.

      Parlez-vous français? Um festzustellen, wenn der Kunde weiß, wie zu hand komprimierten Daten müssen auf Daten, die uns in den ersten Platz sendet aussehen. Eine typische Web-Anfrage sieht wie folgt aus (Request Forgery, dann die Details können nicht 100% richtig sein):

      GET index.html HTTP/1.0
      Accept-Typen: */*
      Accept-Encoding: gzip, entleeren
      User-Agent: Mozilla 4.0 (Microsoft Internet Explorer 5.0 kompatibel, NT)

      Was uns interessiert, ist die Linie, die geht Accept-Encoding: gzip, entleeren. Sagt uns, welche Arten der Kodierung des Clients in der Lage ist, zu akzeptieren, und in diesem Fall kann es Daten, die in der gzip-Format sowie das Format der Ablass kodiert wird, zu akzeptieren. Letzteres ist es, was wir brauchen, mal sehen, wie man dieses Wissen in unserem Web-Anwendung zu bekommen. Die Funktion ist ähnlich der folgenden:

      Wir müssen schreiben, die Funktion sieht wie folgt aus:

      Funktion ClientAcceptsDeflate (const Anfrage: TWebRequest): Boolean;
      var
      EncodingTypes: Schnur;
      Start
      // Reiseführer und formatieren Sie die Liste der Kodierungsarten auf Anfrage
      EncodingTypes: = Request.GetFieldByName ('HTTP_ACCEPT_ENCODING');
      EncodingTypes: = Uppercase (StringReplace (EncodingTypes, ',', '/', [rfReplaceAll]));
      EncodingTypes: = '/' + StringReplace (EncodingTypes, '', '', [rfReplaceAll]) + '/';

      // Gibt die Flagge
      Ergebnis: = (Pos ('/ DEFLATE /' EncodingTypes)> 0);
      Ende; // Funktion ClientAcceptsDeflate

      Kurz gesagt, ich habe die Werte neu zu formatieren gzip, entleeren in / GZIP/DEFLATE / und prüfen Sie dann, wenn die Zeichenfolge / DEFLATE / ist darin. Wenn Sie daran interessiert zu wissen, was anderen Felder können in der Anforderung zu finden sind, dann empfehle ich Ihnen einen Blick auf http://msdn.microsoft.com/library/psdk/iisref/isre504l.htm und verwendet die Variable ALL_HTTP überprüfen Variablen, wie der Client tatsächlich sendet.

      Naturelle, parlons! Nachdem wir festgestellt, dass der Kunde komprimierten Daten verarbeiten alles, was wir haben noch zu tun ist eigentlich die komprimierten Daten zu erzeugen, und das ist, wo die Magie kommt.

      Wie bereits erwähnt, werden wir die Kompressionsbibliothek zlib verwenden, um die Kompression der Realität zu tun. Der Code enthält die folgenden Schritte:

      1. Eingestellt Puffer für die Datenzufuhr zu dem Motor und die komprimierten Daten von ihm akzeptiert
      2. Die Kompressions-Engine initialisieren
      3. Geben Sie die Klartext-Daten in den Eingangspuffer aus dem Eingangsstrom
      4. Komprimieren der Eingabepuffer an den Ausgabepuffer
      5. Schreiben der Daten aus dem Ausgangspuffer zu dem Ausgangsstrom
      6. Wiederholen Sie die Schritte 3-5, bis Sie wurden mehr Daten im Eingabestrom und Puffer geleert haben
      7. Schließen Kompression
      8. Lassen Sie uns in die Details zu graben und sehen, was wir es zu tun haben:

        Verfahren zLibCompressStream (const Quelle, Ziel: TStream);
        var
        z_s: z_stream;
        rc: Integer;
        // 1. Puffer für Eingang und Ausgang
        Source: Feld [0..BufferSize-1] von Byte;
        Destination: Feld [0..BufferSize-1] von Byte;
        Start
        // 2 Bereiten Sie die Datenmenge zlib
        z_init_zstream (z_s);
        z_s.next_in: = Source;
        z_s.next_out: = Destination;
        z_s.avail_out: = Buffer;

        // 2 Initialisieren Sie die Kompressions-Engine
        deflateInit2 (z_s, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY);

        // Jetzt komprimieren den Fluss
        versuchen
        Wiederholung
        // 3 sehen, wenn wir bekommen, mehr Daten auf die Druckmaschine zu füttern
        wenn (z_s.avail_in = 0) und (Source.Position und dann
        Start
        z_s.next_in: = Source;
        z_s.avail_in: = Source.Read (Source, Puffergröße);
        Ende; // Wenn die Eingabedaten vollständig erschöpft

        // 4 Kompresse Daten
        wenn (z_s.avail_in = 0) und dann
        rc: = entleeren (z_s, Z_FINISH)
        andere
        rc: = entleeren (z_s, Z_STREAM_END);

        // 5 prüfen, ob es Daten an den Zieldruck geschrieben werden
        wenn (z_s.avail_out = 0) oder (rc = Z_STREAM_END) und dann
        Start
        Destination.WriteBuffer (Destination, Buffersize - z_s.avail_out);
        z_s.avail_out: = Buffer;
        z_s.next_out: = Destination;
        Ende; // Wenn die Daten zum Schreiben zur Verfügung stand

        // 6 Wiederholen, bis alle Puffer
        bis (rc Z_OK) oder ((rc = Z_STREAM_END) und (z_s.avail_out Buffersize =) und (z_s.avail_in = 0));
        endlich
        // 7 Reinigen Sie das Daten-Engine
        deflateEnd (z_s);
        Ende; Versuchen // schließlich - nach sauberen Motor
        Ende; Verfahren // zLibCompressStream

        Wie bisher ist es möglich, die Schritte in diese Liste mit Kommentaren über nummerierte kombinieren. Der Grund, warum wir nicht nutzen konnten die zlib-Code das? S in Delphi enthalten ist, dass es versteckt die Routine und die deflateInit2 bei der Umsetzung ein Teil der Gruppe benötigten Parameter, um nicht den gesamten erforderlichen Code aus.

        Um Druckdaten, so dass der Browser umgehen kann produzieren, müssen wir Daten ohne Kopfsatz zu komprimieren. Der Kopfsatz ist ein wenig Rekord von Informationen, die ganz am Anfang der komprimierten Daten geschrieben werden, und hilft dem Dekomprimierungsmaschine wissen, wie viel Daten, die folgen. Wir können beschließen, dass diese Kopfsatz, indem Sie einen negativen Wert für den Parameter wBitSize das Verfahren deflateInit2 schreiben. Da der Standard die Luft aus dem Browser haften nicht erwarten oder wissen, wie man diesen Header umgehen, müssen wir herausfiltern. Da wir deflateInit2 nicht direkt mit der zlib-Code mit Delphi geliefert nennen wir mussten auf eine Kopie der DLL volle Komprimierungsbibliothek zurückgreifen.

        Die Kompression in der Lage ist, die Daten aus dem Eingangspuffer zu komprimieren und zu schreiben, um den Ausgangspuffer. Wenn der Ausgabepuffer voll ist, unseren Code brauchen sie, um den Puffer zu spülen und Schreiben von Daten in es zum Ziel, in unserem Fall ein Strom. Wenn es in der Lage, alle Daten aus den Eingabepuffer zu komprimieren ist, muss unser Code, um den Puffer wieder mit, so viele Daten wie möglich zu füllen. Die Komprimierungsmaschine übernimmt den Rest.

        Testen Sie Ihre Web-Anwendung itAfter kompilieren (siehe unten auf der Artikel für eine Kopie der Beispielprojekt in diesem Artikel implementiert), sollten Sie im Idealfall versuchen Sie es sowohl mit einem Browser, der komprimierten Daten verarbeitet, und eine, die nicht. Sie können Internet Explorer 5.4 und Netscape 4.6 als ehemaliger wie diese zu verwenden. Der Browser, verarbeitet der Kompression sollte den Text zeigen "Dieser Text wird komprimiert" und die andere "unkomprimiert" zur Verifikation.

        Durchschnittliche Kompressionsrate auf Textinhalte ist etwa 5-6 mal (15-20% der Originalgröße), dann sollte der Effekt auf großen Web-Seiten deutlich sichtbar sein.

        Wickelte sie Upwell, das ist alles. Mit dem Code und Wissen in diesem Artikel enthaltenen sollten Sie jetzt in der Lage, mit den komprimierten Daten von Ihrem Web-Anwendung zu befassen. Obwohl wir eine ISAPI-DLL in diesem Artikel erstellt, sollte der Theorie und der Code das gleiche für die NSAPI und CGI-Anwendungen bleiben.

        Ich habe mir die Freiheit genommen, um eine Einheit mit den beiden oben beschriebenen Funktionen, sowie eine Kopie der Beispiel in diesem Artikel gemacht erstellen. Sie können die Dateien aus der Auswahl unten herunterladen. Wenn es irgendwelche Vorschläge oder Dinge, die Sie kommentieren möchten können lasse@cintra.no erreicht werden.

        Datei zum Download:

        • zlib DLL (von Autoren-Website)
        • Einfuhrstück zlib.dll
        • Beispiel für ein Projekt (einschließlich Einheiten mit den beiden Funktionen und Import-Unit)
        • Nur die Einheit mit den beiden Funktionen, die wir geschrieben haben

        Es gibt ein paar Hinweise von Abschluss im Auge zu behalten:

        • Die Kompression Motor nicht festzustellen, ob die Daten bietet sich einfach an Kompression oder nicht, bevor sie anfangen zu kauen auf sie. Dies bedeutet, dass Sie die Daten durch sie zu füttern, die nicht komprimiert werden kann und darf auch in der Größe zu erhöhen, statt. Für Text und Web-Seiten ist kein Problem, wie auch immer, aber ich würde gerne ein paar Tests vor der Zuführung es im JPEG-oder GIF-Format zu tun.
        • Die Kompression ist auf der Server-Seite, bevor sie gesendet werden, so, wenn der Client versucht, eine große Web-Seite herunterladen dann ist die Web-Anwendung im wesentlichen lädt die gesamte Seite im Speicher an, verdichtet sie und sendet sie getan. Wenn der Speicherverbrauch auf dem Server ist ein Problem, dann würde ich die Umsetzung des Komprimierungscode in einer Klasse aus TStream abgeleitet legen nahe, dass, wenn Sie von ihm gelesen komprimiert. Auf diese Weise wird die Kompressions on-the-fly durchgeführt, wie die Daten gesendet werden und können direkt von der Platte durch den Kompressions-Bibliothek an den Kunden betrieben werden. Klassen, dies zu tun sind von der Homepage des Paket namens StreamFilter.

(0)
(0)

Kommentare - 0

Keine Kommentare

Fügen Sie einen Kommentar

smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile smile smile smile smile
smile smile smile smile
Zeichen übrig: 3000
captcha