通过GZIP 对Web Service进行压缩

由于目前的GPRS网络带宽比较小,在进行移动应用开发的时候,可以考虑通过GZIP 对Web Service进行压缩.
下面是一个 虑通过GZIP 对Web Service进行压缩的SoapExtension例子.

using System;
using System.Text;
using System.IO;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ICSharpCode.SharpZipLib.Checksums;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.GZip;

namespace WsClient
{
    class ServerSoapExtension : SoapExtension
    {
        private Stream networkStream;   //ChainStream原来的流
        private Stream newStream;       //ChainStream新建的流

        public override object GetInitializer(Type serviceType)
        {
            //throw new Exception("GetInitializer() is not implemented.");
            return null;
        }

        public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            //throw new Exception("GetInitializer( ,) is not implemented.");
            return null;
        }

        public override void Initialize(object initializer)
        {
            //throw new Exception("Initialize() is not implemented.");

        }

        //bool is_AfterSerialize = false;

        public override void ProcessMessage(SoapMessage message)
        {
            switch (message.Stage)
            {
                case SoapMessageStage.BeforeSerialize:
                    break;
                case SoapMessageStage.AfterSerialize:
                    AfterSerialize(message);
                    break;
                case SoapMessageStage.BeforeDeserialize:
                    BeforeDeserialize(message);
                    break;
                case SoapMessageStage.AfterDeserialize:
                    break;
                default:
                    throw new Exception("invalid stage");
            }
        }

        /**********************************************************************************/
        //对 Stream 的引用在任何 SoapMessageStage 之前传入 ChainStream 一次。
        public override Stream ChainStream(Stream stream)
        {
            networkStream = stream;
            newStream = new MemoryStream();
            return newStream;
        }

        private void SaveStream(Stream stream, string filename)
        {
            stream.Position = 0;
            FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            sw.Flush();
            copy(stream, fs);
            sw.Close();
            stream.Position = 0;
        }

        //序列化之后调用
        public void AfterSerialize(SoapMessage message)
        {
            //压缩数据
            Comp(message.Stream, networkStream);
        }

        //反序列化之前调用
        public void BeforeDeserialize(SoapMessage message)
        {
            System.Diagnostics.Debug.Print("newStream:" + newStream.GetHashCode().ToString());
            System.Diagnostics.Debug.Print("message.Stream:" + message.Stream.GetHashCode().ToString());
            //解压数据
            Decomp(networkStream, message.Stream);
        }

        //流复制
        public void copy(Stream fromStream, Stream toStream)
        {
            StreamReader reader = new StreamReader(fromStream);
            StreamWriter writer = new StreamWriter(toStream);
            writer.WriteLine(reader.ReadToEnd());
            writer.Flush();
        }

        //流解压
        public void Decomp(Stream fromStream, Stream toStream)
        {

            //fromStream.Position = 0;
            Stream s = new GZipInputStream(fromStream);
            int size = 2048;
            byte[] writeData = new byte[2048];
            while (true)
            {
                size = s.Read(writeData, 0, size);
                if (size > 0)
                {
                    toStream.Write(writeData, 0, size);
                }
                else
                {
                    break;
                }
            }
            s.Close();
            toStream.Position = 0;


        }
        //流压缩
        public void Comp(Stream fromStream, Stream toStream)
        {

            Stream s = new GZipOutputStream(toStream);
            byte[] writeData = new byte[fromStream.Length];
            fromStream.Position = 0;
            fromStream.Read(writeData, 0, (int)fromStream.Length);
            s.Write(writeData, 0, writeData.Length);
            s.Close();
        }

        private string ConverByteToString(byte[] buffer)
        {

            Decoder decoder = System.Text.Encoding.UTF8.GetDecoder();
            int charlen = decoder.GetCharCount(buffer, 0, buffer.Length);
            char[] chars = new char[charlen];
            int Length = decoder.GetChars(buffer, 0, buffer.Length, chars, 0);

            return new string(chars);
        }

        private byte[] ConvertStrToByte(string sourceStr)
        {
            Encoder defEncoder = Encoding.Default.GetEncoder();
            int byteCount = defEncoder.GetByteCount(sourceStr.ToCharArray(), 0, sourceStr.Length, true);

            byte[] bytes = new Byte[byteCount];

            int bytesEncodedCount = defEncoder.GetBytes(sourceStr.ToCharArray(), 0, sourceStr.Length, bytes, 0, true);
            return bytes;
        }
    }


    [AttributeUsage(AttributeTargets.Method)]
    public class ServerSoapExtensionAttribute : SoapExtensionAttribute
    {
        private int priority;

        public override Type ExtensionType
        {
            get
            {
                return typeof(ServerSoapExtension);
            }
        }

        public override int Priority
        {
            get
            {
                return priority;
            }
            set
            {
                priority = value;
            }
        }
    }
}

posted @ 2006-07-09 23:18  Yonglun  阅读(1717)  评论(7编辑  收藏  举报