|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionHold on, I know there is no picture involved, give it a chance all the same, especially if you are a Web services developer ;-) While writing WebServices, in cases where the client and the server have to communicate through the web, the cost of transferring data through the network is becoming an issue, costly both in the aspect of general responsiveness and the network load. This lib Zips the SOAP envelope body at the server side, and unzips it back in the client side, behind the scenes, through the use of SOAP filters. BackgroundThere are some common recommendations that one should follow when writing such an app, amongst which you can find the following list:
Having that said, sometimes you do need to pass a big chunk of data through the web, usually a chubby I have written a Zip and a corresponding Unzip filter that you very simply add to your Web service (adding a reference and a filter declaration in the web.config file) and to your WinForms client (again, a reference and a line of code), and you're set. There is absolutely no code changes to make nor any other overhead. The code descriptionThe code is a DLL that should be referenced by both projects - client and server, and consists of 3 simple classes: The ZipWrapper
The Zip type I'm using is GZip; although not the best compression, it is extremely faster than its brother the BZip2, and proved more desired in our case. The ZipFilter
This class can also determine the zipping method. The UnZipFilter
Code snippetWe must override the public override void ProcessMessage(SoapEnvelope envelope)
{
if ( !m_bEnabled )
return;
//adding an attribute to specify that the filter has been
//applied on this envelope.
XmlElement soapHeader = envelope.CreateHeader();
if ( envelope.Body.InnerText.Length < ( m_MinFilterSize ) )
return;
else
soapHeader.AppendChild(CreateCustomHeader(soapHeader, "1" ));
//compress the body element.
MemoryStream result = new
MemoryStream( ZipWrapper.Compress(
Encoding.UTF8.GetBytes( envelope.Body.InnerXml ) ) );
//Attach zipped result to the envelope.
Microsoft.Web.Services2.Attachments.Attachment attch =
new Microsoft.Web.Services2.Attachments.Attachment(
"APPLICATION/OCTET-STREAM",result );
envelope.Context.Attachments.Add( attch );
//remove old body.
XmlElement newBody = envelope.CreateBody();
newBody.RemoveAll();
envelope.SetBodyObject( newBody );
}
Using the libPrerequisites
Server side usage
In order to config the filter, you should set its attributes: // setting minimum zip size requirement to 10KB.
WebServiceZipFilter.ZipFilter.MinFilterSizeKB = 10;
// enabling the filter
WebServiceZipFilter.ZipFilter.Enabled = true;
Please take note: it is strongly recommended to set these values through values from a configurable part in the web.config, so it can be dynamically changed according to the tuning requirements. Client side usageImportant note: Many users out there have repeatedly asked me if it is possible to work in duplex mode and if the client side can be configured as the server does. The answer is yes and yes. The list below is an alternative code to add the filter to the pipeline, but you can add the necessary sections to the app.config file and get it done without coding (see the "Server side usage" section above). Regarding the duplex mode, both sides can zip and unzip without a worry!
Some empirical resultsI've conducted my tests on a server, dedicated to me only, that is located in a web farm in my hometown, providing a 5MB download and 1 MB upload, using an ADSL 750 KB connection on a relaxed weekend noon, so the conditions were optimal for the non-zipping tests, and still the differences are quite notable: Sending 570 records of heterogeneous data took around 2.281 seconds without zipping, compared with 1.843 seconds with zipping (20% reduction). Sending 10570 records (570 heterogeneous data + 10000 different although similar dummy records) took around 29.43 seconds without zipping, compared with 6.04 seconds with zipping (80% reduction !!!). A completely heterogeneous data would have made the difference negligible. Future versionsWill there be any? Apparently not. Is this good news? Yes! Why? Because folks at Redmond realized the compression feature is missing, and a few good men released the WCF implementation, and those same guys also released a version for WSE 3.0 here, so my mission is quite done. Everyone is happy. Resources
History
You are strongly urged to review and comment. Happy coding.
|
||||||||||||||||||||||