2011-01-08 3 views
2

Ich habe kürzlich einen benutzerdefinierten Encoder eingesteckt (verwendet Binär-Encoder, um die tatsächliche Codierung und Gzip-Komprimierer zu tun, um das Byte-Array zu komprimieren). Es funktioniert gut. Das Problem besteht jetzt für eine kleine Nachrichtengröße, die tatsächlich das Byte-Array aufbläst. Ich würde gerne wissen, ob es einen Weg gibt, dies zu vermeiden. Insbesondere, wenn es einen Weg gibt, kann ich Condition Compression und Dekompression anwenden.wcf bedingte Komprimierung

Ich habe versucht, wie etwas zu tun - legen Sie eine Bedingung

if(buffer.Count <= 5000) 
skip compression 

Aber das Problem ist auf das andere Ende Dekompression auch passieren wird, wenn die Bytes nicht komprimiert werden. Ich hoffe das macht Sinn.

Im Folgenden sind die Funktionen, bei denen die Komprimierung und Dekomprimierung geschieht (Code-Schnipsel aus CompactMessageEncoder)

public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType) 
     { 

      ArraySegment<byte> decompressedBuffer = DecompressBuffer(buffer, bufferManager); 
      LogWrite("Decompressed from {0} bytes to {1} bytes", buffer.Count, decompressedBuffer.Count); 

      Message returnMessage = _innerEncoder.ReadMessage(decompressedBuffer, bufferManager); 

      returnMessage.Properties.Encoder = this; 
      return returnMessage; 
     } 



public override ArraySegment<byte> WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset) 
     { 
      var buffer = _innerEncoder.WriteMessage(message, maxMessageSize, bufferManager, messageOffset); 

      var compressedBuffer = CompressBuffer(buffer, bufferManager, messageOffset); 
      LogWrite("Compressed from {0} bytes to {1} bytes", buffer.Count, compressedBuffer.Count); 

      return compressedBuffer; 
     } 
+0

könnten Sie einen custome Header zu den Nachrichten hinzufügen, die komprimiert wurden? http: // Stapelüberlauf.com/questions/964433/How-to-Add-a-Custom-Header-to-Every-WCF-Aufrufe –

+0

@Mitch: Dies funktioniert möglicherweise nicht. Da ich hinzufügen muss Lets sagen, ich füge benutzerdefinierte Header der Message-Klasse und komprimieren sie in WriteMessage() -Funktion. In der ReadMessage() muss ich es dekomprimieren, bevor ich die Message-Klasse bekomme und den Header lese. – stackoverflowuser

Antwort

0

Könnten Sie ein Byte schreiben, ob die Daten komprimiert wurde anzeigen würde, oder nicht? 0 = unkomprimiert, 1 = Gzip komprimiert, 2 - 255 = Künftige Komprimierungsalgorithmen?

Sie könnten die unkomprimierte Länge schreiben, aber das würde darauf beruhen, dass der Server und der Client die gleiche Cutoff-Länge verwenden, um nicht zu komprimieren. Sie könnten einen Booleschen Wert schreiben, der angibt, ob es komprimiert ist, aber das würde immer noch ein ganzes Byte dauern, und Sie können sich für zukünftige Erweiterungen offen lassen, indem Sie einen Wert zwischen 0 und 255 schreiben. (Vielleicht entdecken Sie, dass ein anderer Komprimierungsalgorithmus mit Ihren Daten eine noch bessere Komprimierung ermöglicht.)

2

Falls Sie http verwenden und wenn Sie auf IIS 7 oder höher sind (es ist auch möglich mit 6, aber Konfiguration ist anscheinend härter), könnten Sie die eingebaute gzip/deflate-Komprimierung verwenden.

Siehe http://www.iis.net/ConfigReference/system.webServer/httpCompression

Dieser Zusammenhang erklärt auch Parameter wie ‚minFileSizeForComp‘, die genau Ihr Problem behebt. Es hat auch viele andere nette Parameter wie 'dynamicCompressionDisableCpuUsage', die die Komprimierung deaktiviert, sobald eine bestimmte CPU-Auslastung überschritten wird.

Die nette Sache über HTTP-Komprimierung ist, dass es ein Standard ist und Client und Server pro Anfrage bestimmen können, ob sie unter Verwendung von Standard-HTTP-Request- und Response-Headern komprimieren können oder wollen. Außerdem kann das Komprimierungsformat von gzip in deflate geändert werden, wobei letzteres einige Vorteile bietet, obwohl es nicht so oft verwendet wird. Siehe http://madskristensen.net/post/Compression-and-performance-GZip-vs-Deflate.aspx und http://www.vervestudios.co/projects/compression-tests/

Ein möglicher Nachteil - auf Ihrer Anwendung abhängig ist, dass die HTTP-Komprimierung nur vom Server durchgeführt wird -> Client, also, wenn Ihre Anfragen sind riesig, das könnte ein Problem werden, aber in der wohl die meisten Fällen Serverantworten sind viel größer als Clientanfragen. Edit: Wenn Sie bereit sind, eine custom IHttpModule hinzuzufügen, können Sie sogar Anfrage Komprimierung arbeiten.

Ich habe gerade eine stark genutzte Farm von 20 Servern von GZIPMessageEncoder auf die http-Komprimierung von IIS 7.5 migriert.

Nebenbei, bitte verwenden Sie nicht das GzipMessageEncoder-Beispiel von MS im gepufferten Übertragungsmodus, was der Standard ist. GzipMessageEncoder verschwendet nur Tonnen von Speicher - Hunderte von Megabyte in meinem speziellen Fall, siehe meine Antwort hier: WCF HttpTransport: streamed vs buffered TransferMode