and procedures are not introduced in this article how to use WCF, but how in the WCF communication channels at both ends automatically when the data compression and decompression, thereby increasing the speed of data transmission distributed. Moreover, this process is completely transparent, users and programmers do not need to know its existence, which is equivalent to HOOK a component in both ends. Network bandwidth can be used in smaller network environments. When the WCF communication between the two entities in time, it automatically creates an information communication channel adapter, the message contains the request and the corresponding data. WCF encoder to use a special request and response data will be converted into a series of bytes.
brought about by the projects I encountered the issue of transfer large files distributed through analysis to consider the use of WCF channel compression technology to solve this problem. The implementation of such a code is the need to transfer large files (XML format) from one machine to another machine transmission, and connection speed limit. I do not have to write a function of a special edge compression and decompression side, but transmission channel can be configured to do this, this compression can be used in any contract. I found the information to prepare their own encoder is the simplest way to achieve the function, the real question is how the preparation of information coding, and in the MSDN did not find any examples on the application. Compact message encoder Hook idea is to connect both ends to send and receive information. Procedure is the use of Microsoft Visual Studio 2008 WCF design.
Figure 1 WCF news channel coding process timing diagram p>
sender: to add code method and its parameters into a SOAP message sequence, message coding sequence of the information will be a byte array, byte array to send the transport layer.
recipient: byte array to receive the transport layer, message encoders in parallel an array of bytes to a message, the method and its parameters parallel to a SOAP message is being monitored. When adding information compression encoder, the method requires a little change: sender: to add code method and its parameters into a SOAP message sequence, message encoding lease information to the internal coding sequence information into a byte array , the news leases Coding byte array of the second byte array, byte array to send the transport layer. Recipient: byte array to receive the transport layer, the news leases extracting encoded byte array to the second byte array, the news leases to the internal coding of the information encoded byte array of the second message, the method and its parameters parallel to the SOAP message is being monitored.
Compact encoding
the news is divided into several categories:
- CompactMessageEncoder / / This class provides the implementation of information coding.
- CompactMessageEncoderFactory / / This class is responsible for the provision of contract information coding examples.
- CompactMessageEncodingBindingElement / / this type of agreement is responsible for channel norms.
- CompactMessageEncodingElement / / this type of information coding by increasing the application configuration file.
news channel
Figure 2 encoder static class diagram
compression method: Compact source encoder is to use gzip compression to implement NET Framework is called Namespace System.IO.Compression.GZipStream category. Adding references CompactMessageEncoder.dll, modify app.config file references, the application must be on the client and server-side.
compression buffer
code:
private static ArraySegmen t CompressBuffer (ArraySegment buffer, BufferManager bufferManager, int messageOffset) (/ / Create a memory stream for the final message MemoryStream memoryStream = new MemoryStream (); / / Copy the bytes that should not be compressed into the stream memoryStream.Write (buffer.Array, 0, messageOffset); / / Compress the message into the stream using (GZipStream gzStream = new GZipStream (memoryStream, CompressionMode.Compress, true)) (gzStream.Write (buffer.Array, messageOffset, buffer.Count);) / / Convert the stream into a bytes array byte [] compressedBytes = memoryStream.ToArray (); / / Allocate a new buffer to hold the new bytes array byte [] bufferedBytes = bufferManager.TakeBuffer (compressedBytes.Length); / / Copy the compressed data into the allocated buffer Array.Copy (compressedBytes, 0, bufferedBytes, 0, compressedBytes.Length); / / Release the original buffer we got as an argument bufferManager.ReturnBuffer (buffer.Array); / / Create a new ArraySegment that points to the new message buffer ArraySegment byteArray = new ArraySegment (bufferedBytes, messageOffset, compressedBytes.Length - messageOffset); return byteArray;)
decompression buffer
code:
private static ArraySegment DecompressBuffer (ArraySegment buffer , BufferManager bufferManager) (/ / Create a new memory stream, and copy into it the buffer to decompress MemoryStream memoryStream = new MemoryStream (buffer.Array, buffer.Offset, buffer.Count); / / Create a memory stream to store the decompressed data MemoryStream decompressedStream = new MemoryStream (); / / The totalRead stores the number of decompressed bytes int totalRead = 0; int blockSize = 1024; / / Allocate a temporary buffer to use with the decompression byte [] tempBuffer = bufferManager.TakeBuffer (blockSize ); / / Uncompress the compressed data using (GZipStream gzStream = new GZipStream (memoryStream, CompressionMode.Decompress)) (while (true) (/ / Read from the compressed data stream int bytesRead = gzStream.Read (tempBuffer, 0, blockSize) ; if (bytesRead == 0) break; / / Write to the decompressed data stream decompressedStream.Write (tempBuffer, 0, bytesRead); totalRead + = bytesRead;)) / / Release the temporary buffer bufferManager.ReturnBuffer (tempBuffer); / / Convert the decompressed data stream into bytes array byte [] decompressedBytes = decompressedStream.ToArray (); / / Allocate a new buffer to store the message byte [] bufferManagerBuffer = bufferManager.TakeBuffer (decompressedBytes.Length + buffer.Offset); / / Copy the bytes that comes before the compressed message in the buffer argument Array.Copy (buffer.Array, 0, bufferManagerBuffer, 0, buffer.Offset); / / Copy the decompressed data Array.Copy (decompressedBytes, 0, bufferManagerBuffer, buffer. Offset, decompressedBytes.Length); / / Create a new ArraySegment that points to the new message buffer ArraySegment byteArray = new ArraySegment (bufferManagerBuffer, buffer.Offset, decompressedBytes.Length); / / Release the original message buffer bufferManager.ReturnBuffer (buffer.Array); return byteArray;)
change the server configuration
to join before the news leases app.config encoder example:
by adding after the news leases app.config encoder example:
client configuration changes
to join before the news leases app.config encoder example:
by adding after the news leases app.config encoder example: p>
; < ! - Defines a new customBinding that contains the compactMessageEncoding> ; configuration>
this compression method, a very small chance of blocking messages. CompactMessageEncoder use the same machine running the client and server may reduce efficiency.
Download
source: CompactMessageEncoder_src.zip (886.97 kb)