2

I have a Silverlight project getting data from an IIS 7.0 server via WCF web services. The data returned is usually large, so compression seemed like a good option. However, for the life of me, I can't get it to work.

Here's what I tried so far

  • Enabled compression (dynamic and static) for all mime types (/). Verified that it works (a hit on an aspx page returns gzipped data as per fiddler)
  • Did a whole lot of digging around on WCF and compression. I read something along the lines of WCF 4.5 having something to enable / disable gzip. I'm not sure if this means that IIS 7.0 dynamic compression cannot be used, or if its something unrelated.
  • Also got a few examples on using GZipEncoder (from Microsoft WCF Samples)

And here's what I'd like to find out

  • With Silverlight reading data from WCF hosted on an IIS 7.0 server with .NET 4.0, is it possible to turn on compression for the XML responses by simply messing around with the Web.Config / applicationHost.Config?
  • If not, what is the easiest way to get it to work (say, add a dll, change my Web.Config and done!)

Thanks folks!

Edit: Thanks for all the answers folks. Just one quick note - if someone can confirm that it does not work for WCF 4.0 "or" works with WCF 4.0 only if you do this, that'd help.

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
  • Are you limited to using HTTP? – Petar Vučetin Oct 12 '13 at 16:04
  • Sorry, I didn't quite get your question. HTTP vs ?. The site and the WCF are hosted on https urls, if that was the question. Thanks! – potatopeelings Oct 14 '13 at 18:46
  • You have an alternative bindings to HTTP. One of them is TCP which uses binary encoder. Binary encoder is better then text encoder (XML) when it comes to the size of the message. Silverlight 4 supports a subset of NetTcpBinding. It does not support TLS (as far as I know) so that might be a problem if you need point-to-point security. – Petar Vučetin Oct 14 '13 at 19:33
  • Security is where I got stuck with on when trying to make it binary encoding :-(. But thanks for your comments - at least that's one thing I won't have to try again on :-) – potatopeelings Oct 15 '13 at 14:31

2 Answers2

1

We've got GZip compression working for WCF, I'll try to backtrack what we did to get it working. There are a few gotcha's which might bite you trying to get this to work (personally I'm moving trying to move away from WCF wherever possible).

Firstly you need to have IIS Dynamic Compression installed. Secondly you must use browser http in the Silverlight app (which is the default in browser, but not when running OOB) since the build-in http stack doesn't support GZip compression. You can force this in the Application_Startup() function (change http to https if required).

WebRequest.RegisterPrefix("http://", System.Net.Browser.WebRequestCreator.BrowserHttp);

The gotcha here is that you will only ever get generic errors in your client when a webservice call fails because the browser stack doesn't pass the content of an http 500 response on to Silverlight. Is this is an issue for you it can be worked around with a custom MessageInspector which changes the response code to 200 always.

In your web.config you need to enable dynamic compression

<system.webServer>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />

On top of that you need to have the mime type registered in IIS, we added this to the applicationHost.config for WCF with binary message encoding.

<add mimeType="application/soap+msbin1" enabled="true" />

If your not using binary message encoding you probably need application/soap+xml instead here. If I recall correctly these are all the steps needed.

The last gotcha though, it doesn't help when your client is sending large messages since there is no way (afaik) to make silverlight actually send gzip compressed requests to the server, so your only gain will be on the data send by the server.

AVee
  • 3,348
  • 17
  • 17
  • Got dyanmic compression installed (actually went one step further - made sure that dynamic content generated by an aspx was being zipped). It's silverlight in a browser, so I hope the RegisterPrefix was not needed. And yep had the do...Compression tag and the mimeTypes added. And nope, don't have much of a problem with the client sending large messsages. It's only the server I'm worried about. Were you working with WCF 4.0? – potatopeelings Oct 15 '13 at 14:29
  • Yes, we're using WCF 4. I recon you don't need the RegisterPrefix, but you might want to check using fiddler is the requests contain 'Accept-Encoding: gzip, deflate'. Also, if you use Fiddler to check disable automatic decoding, otherwise you won't see if gzip is used or not. – AVee Oct 15 '13 at 15:12
  • Yep, the requests contain Accept Encoding. And automatic decoding is disabled in Fiddler. So back to the drawing board for me :-( – potatopeelings Oct 17 '13 at 14:51
  • Am marking this as the answer since it answers the question - does IIS dynamic compression work with WCF 4.0. Thank you Avee! – potatopeelings Oct 17 '13 at 14:53
  • Perhaps you could start with a test to see if IIS is setup correctly. I'd assume it should gzip an aspx page which sets it's content type to the same content type you see on your wcf response messages in fiddler. If that test page is not compressed you should be looking at the IIS setup. – AVee Oct 17 '13 at 19:10
0

There are several options for compression with WCF over HTTP. Each have their advantages and disadvantages.

IIS dynamic compression

This is compression on the HTTP layer, and is the most performant, since it runs at the lowest level. It is also the most standard, thus will work with other web technologies easily.

Unfortunately the main disadvantage is that it was based on old web technology (HTTP) where there was the old belief that upstream data is limited and only downstream payload is worth compressing. Therefore upstream data isn't compressed.

Message Compression

Starting with .net 4.5 the message encoders have a new property on MessageEncoder to allow you to enable compression. This is done on the .net layer, and thus is much slower than IIS compression. It is also proprietorial and thus can be difficult to use with non-dot-net technologies. This tech is not availible for SilverLight.

Aron
  • 15,464
  • 3
  • 31
  • 64
  • Sorry, I'm kind of stuck with .NET 4.0. One way compression is fine. I just need the server to client side data compressed (I assume that is what you mean by downstream). Is this possible (site and WCF hosted on https) by simply changing the IIS settings or Web.Config? – potatopeelings Oct 14 '13 at 18:48
  • No you can not JUST set it on the `web.config`. There is a few parts that require elevated access to the machine. First you need to install `IIS Dynamic Compression` (your test only proved that you have `IIS Static Compression` installed). Then you have to add the mime types as you have done. Finally you need to ensure that your CPU never reaches 90%, as that automagically turns off compression. http://www.hanselman.com/blog/EnablingDynamicCompressionGzipDeflateForWCFDataFeedsODataAndOtherCustomServicesInIIS7.aspx – Aron Oct 15 '13 at 01:46
  • Sorry I hadn't mentioned that - I also had dynamic compression installed and I verified it was working by checking that dynamic conentent generated by an aspx file was being gzipped (via Fiddler). I removed that CPU limit by adjusting the application.config. But it still didn't work (with WCF 4.0) – potatopeelings Oct 15 '13 at 14:34
  • Have you set the WCF to buffered mode? – Aron Oct 15 '13 at 14:39