Error message

  • Warning: Cannot modify header information - headers already sent by (output started at /hsphere/local/home/c327781/sibertec.com/index.php:1) in drupal_send_headers() (line 1485 of /hsphere/local/home/c327781/sibertec.com/includes/bootstrap.inc).
  • Warning: Cannot modify header information - headers already sent by (output started at /hsphere/local/home/c327781/sibertec.com/index.php:1) in drupal_send_headers() (line 1485 of /hsphere/local/home/c327781/sibertec.com/includes/bootstrap.inc).
  • Warning: Cannot modify header information - headers already sent by (output started at /hsphere/local/home/c327781/sibertec.com/index.php:1) in drupal_send_headers() (line 1485 of /hsphere/local/home/c327781/sibertec.com/includes/bootstrap.inc).
  • Warning: Cannot modify header information - headers already sent by (output started at /hsphere/local/home/c327781/sibertec.com/index.php:1) in drupal_send_headers() (line 1485 of /hsphere/local/home/c327781/sibertec.com/includes/bootstrap.inc).
  • Warning: Cannot modify header information - headers already sent by (output started at /hsphere/local/home/c327781/sibertec.com/index.php:1) in drupal_send_headers() (line 1485 of /hsphere/local/home/c327781/sibertec.com/includes/bootstrap.inc).
  • Warning: Cannot modify header information - headers already sent by (output started at /hsphere/local/home/c327781/sibertec.com/index.php:1) in drupal_send_headers() (line 1485 of /hsphere/local/home/c327781/sibertec.com/includes/bootstrap.inc).

Web Service Compression for the .Net Compact Framework

I was working on a project for a client who was developing a web service to load data from an SQL Server database onto a Windows CE device. The project was already well under way before I was asked to do some work on it. The web service was easy enough to get running, but because of the way xml web services are implemented, it required a huge amount of bandwidth to send even a small amount of data. And a normal download could be thousands of records.

After much Googling and not a few failed attempts, I finally found a way to compress the data sent to and from a Windows CE device.

I found the key to the solution at the web site http://www.flowgroup.fr/en/kb/technical/compressionhttp.aspx.

They had a code sample that I downloaded and converted from C# to VB.Net. The only change I needed to make was to add one line.

The solution uses SharpZipLib to do the compression and decompression on the handheld device. It works on both Windows CE and PocketPC.

In addition to the code for the Windows CE device, the web server must be set up to allow the client to request a compressed response. For instructions on how to enable http compression on IIS, see http://www.wwwcoder.com/main/parentid/170/site/3669/68/default.aspx.

This is the code module that I added to the VB.Net project:

 Imports System.IO  
 Imports System.Net  
 Imports ICSharpCode.SharpZipLib.GZip  
 Imports ICSharpCode.SharpZipLib.Zip.Compression.Streams  
   
 Namespace FlowGroup.Net  
   
   Friend Class ZHttpWebRequest  
     Inherits System.Net.WebRequest  
   
     Private request As HttpWebRequest  
     Private uri As System.Uri  
   
     Friend Sub New(ByVal uri As System.Uri)  
   
       Dim s As String = uri.AbsoluteUri.Substring(1) '// remove the leading z  
       Me.uri = uri  
       request = CType(WebRequest.Create(s), HttpWebRequest)  
   
       '// tell the HTTP server that the client accept compressed data  
       request.Headers.Add("Accept-Encoding", "gzip")  
   
       ' Phil Hopper, 22 MAY 2006: it gives an error if you leave this line out  
       request.AllowWriteStreamBuffering = True  
   
     End Sub  
   
     Public Overrides Function GetResponse() As System.Net.WebResponse  
   
       Dim response As ZHttpWebResponse = Nothing  
   
       '// create the appropriate response object  
       response = New ZHttpWebResponse(request, uri)  
   
       Return response  
   
     End Function  
   
     Public Overrides Sub Abort()  
       request.Abort()  
     End Sub  
   
     Public Overrides Function BeginGetRequestStream( _  
       ByVal callback As System.AsyncCallback, _  
       ByVal state As Object) As System.IAsyncResult  
   
       Return request.BeginGetRequestStream(callback, state)  
   
     End Function  
   
     Public Overrides Function BeginGetResponse( _  
       ByVal callback As System.AsyncCallback, _  
       ByVal state As Object) As System.IAsyncResult  
   
       Return request.BeginGetResponse(callback, state)  
   
     End Function  
   
     Public Overrides Function EndGetRequestStream( _  
       ByVal asyncResult As System.IAsyncResult) _  
       As System.IO.Stream  
   
       Return request.EndGetRequestStream(asyncResult)  
   
     End Function  
   
     Public Overrides Function EndGetResponse( _  
       ByVal asyncResult As System.IAsyncResult) _  
       As System.Net.WebResponse  
   
       Return request.EndGetResponse(asyncResult)  
   
     End Function  
   
     Public Overrides Function GetRequestStream() As System.IO.Stream  
       Return request.GetRequestStream()  
     End Function  
   
     Public Overrides Property ConnectionGroupName() As String  
       Get  
         Return request.ConnectionGroupName  
       End Get  
       Set(ByVal Value As String)  
         request.ConnectionGroupName = Value  
       End Set  
     End Property  
   
     Public Overrides Property ContentLength() As Long  
       Get  
         Return request.ContentLength  
       End Get  
       Set(ByVal Value As Long)  
         request.ContentLength = Value  
       End Set  
     End Property  
   
     Public Overrides Property ContentType() As String  
       Get  
         Return request.ContentType  
       End Get  
       Set(ByVal Value As String)  
         request.ContentType = Value  
       End Set  
     End Property  
   
     Public Overrides Property Credentials() As System.Net.ICredentials  
       Get  
         Return request.Credentials  
       End Get  
       Set(ByVal Value As System.Net.ICredentials)  
         request.Credentials = Value  
       End Set  
     End Property  
   
     Public Overrides Property Headers() As System.Net.WebHeaderCollection  
       Get  
         Return request.Headers  
       End Get  
       Set(ByVal Value As System.Net.WebHeaderCollection)  
         request.Headers = Value  
       End Set  
     End Property  
   
     Public Overrides Property Method() As String  
       Get  
         Return request.Method  
       End Get  
       Set(ByVal Value As String)  
         request.Method = Value  
       End Set  
     End Property  
   
     Public Overrides Property Timeout() As Integer  
       Get  
         Return request.Timeout  
       End Get  
       Set(ByVal Value As Integer)  
         request.Timeout = Value  
       End Set  
     End Property  
   
     Public Overrides Property PreAuthenticate() As Boolean  
       Get  
         Return request.PreAuthenticate  
       End Get  
       Set(ByVal Value As Boolean)  
         request.PreAuthenticate = Value  
       End Set  
     End Property  
   
     Public Overrides Property Proxy() As System.Net.IWebProxy  
       Get  
         Return request.Proxy  
       End Get  
       Set(ByVal Value As System.Net.IWebProxy)  
         request.Proxy = Value  
       End Set  
     End Property  
   
     Public Overrides ReadOnly Property RequestUri() As System.Uri  
       Get  
         Return uri  
       End Get  
     End Property  
   
   End Class  
   
   Public Class ZHttpWebResponse  
     Inherits WebResponse  
   
     Private response As HttpWebResponse  
     Private uri As System.Uri  
   
     Protected Sub New()  
       ' default constructor for ZHttpWebResponse  
     End Sub  
   
     Friend Sub New(ByVal request As WebRequest, ByVal uri As System.Uri)  
       Me.uri = uri  
       response = CType(request.GetResponse(), HttpWebResponse)  
     End Sub  
   
     Public Overrides Property ContentLength() As Long  
       Get  
         Return response.ContentLength  
       End Get  
       Set(ByVal Value As Long)  
         'do nothing  
       End Set  
     End Property  
   
     Public Overrides Property ContentType() As String  
       Get  
         Return response.ContentType  
       End Get  
       Set(ByVal Value As String)  
         'do nothing  
       End Set  
     End Property  
   
     Public Overrides Sub Close()  
       response.Close()  
     End Sub  
   
     Public Overrides Function GetResponseStream() As Stream  
       '// select the right decompression stream  
       If (response.ContentEncoding = "gzip") Then  
         Return New GZipInputStream(response.GetResponseStream())  
       ElseIf (response.ContentEncoding = "deflate") Then  
         Return New InflaterInputStream(response.GetResponseStream())  
       Else  
         Return response.GetResponseStream()  
       End If  
     End Function  
   
     Public Overrides ReadOnly Property ResponseUri() As System.Uri  
       Get  
         Return uri  
       End Get  
     End Property  
   
   End Class  
   
   ' Class that creates the zhttp WebRequest instance  
   Friend Class ZHttpWebRequestCreate  
     Implements IWebRequestCreate  
   
     Public Function Create(ByVal uri As System.Uri) As WebRequest _  
     Implements IWebRequestCreate.Create  
       Dim request As System.Net.WebRequest = New ZHttpWebRequest(uri)  
       Return request  
     End Function  
   End Class  
   
   ' Class that registers the zhttp protocol  
   Public Class ZHttpProtocol  
   
     ' Register the protocol  
     Public Shared Function Register() As Boolean  
       Return WebRequest.RegisterPrefix("zhttp", New ZHttpWebRequestCreate)  
     End Function  
   
   End Class  
   
 End Namespace  
   

To register the "ZHTTP" protocol on the handheld device, I call "ZHttpProtocol.Register()" in sub Main.

The final step is to preappend a z to the url of the web service:

 Dim ws As New MyWebService.MyClass

 'this is for compression 
 ws.Url = "z" & ws.Url

You can download the code as zip files below:

http://www.sibertec.com/downloads/compression/cf/sharpziplib.zip 
http://www.sibertec.com/downloads/compression/cf/zhttpvb.zip