webservice传输数据量较大的情况的解决方案

目前遇到的项目服务器端是java平台的,客户端是.net的,而且网络情况不定,所以服务器端采用webservice方式向客户端提供数据。
这样的情况下传输数据的量就成为影响性能的瓶颈之一。
刚开始我们针对某些返回数据量较大的方法采用gzip压缩,那么在客户端直接进行解压缩,由于不是重点直接上方法:
代码
/// <summary>
/// 对内容进行解压缩
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public String Decompress(byte[] bytes)
{
    
byte[] gzBuffer = bytes;
    String strret 
= "";
    
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(gzBuffer))
    {
        
using (System.IO.Compression.GZipStream zs = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress))
        {
            
using (System.IO.StreamReader sr = new System.IO.StreamReader(zs))
            {
                strret 
= sr.ReadToEnd();
            }
        }
    }
    
return strret;
}

 

这个时候就产生了一个问题方法多的情况下这样做还是比较麻烦。所以java平台对所有返回的内容都进行压缩这样就省事了,那么针对这样的变化客户端该怎么做可以改动最小呢?
首先增加类CompressSoapExtension继承SoapExtension
然后  override ProcessMessage方法和其他一些方法 那么剩下要做的事情就很简单了
只需要在应用程序的appconfig里增加配置节:
<system.web>
    <webServices>
      <soapExtensionTypes>
        <add type="namespace.CompressSoapExtension, app" group="High" priority="1"/>
      </soapExtensionTypes>
    </webServices>
</system.web>
 
补充下上面继承SoapExtension大致要override的内容:
代码
class CompressSoapExtension : SoapExtension
    {
        
/// <summary>
        
/// 旧流
        
/// </summary>
        private Stream _originStream = null;

        
/// <summary>
        
/// 新流
        
/// </summary>
        private Stream _newStream = null;

        
public override Stream ChainStream(Stream stream)
        {
            
this._originStream = stream;
            
this._newStream = new MemoryStream();

            
return this._newStream;
        }

        
public override object GetInitializer(Type serviceType)
        {
            
return null;
        }

        
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
        {
            
return null;
        }

        
public override void Initialize(object initializer)
        {
        }

        
public override void ProcessMessage(SoapMessage message)
        {
            
switch (message.Stage)
            {
                
case SoapMessageStage.BeforeSerialize:
                    {
                        SoapClientMessage msg 
= message as SoapClientMessage;
                        msg.ContentEncoding 
= "gzip";
                    }
                    
break;
                
case SoapMessageStage.AfterSerialize:
                    {
                        
this._newStream.Position = 0;
                        
this._newStream.CopyTo(this._originStream);
                    }
                    
break;
                
case SoapMessageStage.BeforeDeserialize:
                    {
                        
//判断是gzip头那么就进行解压缩 这样就对原来的程序没有影响了
                        if (string.Compare(message.ContentEncoding, "gzip"true== 0)
                        {
                            
using (GZipStream zs = new GZipStream(this._originStream, CompressionMode.Decompress))
                            {
                                zs.CopyTo(
this._newStream);
                            }
                        }
                        
else
                        {
                            
this._originStream.CopyTo(this._newStream);
                        }

                        
this._newStream.Position = 0;
                    }
                    
break;
            }
        }

 

posted @ 2010-12-30 15:33  neverlost  Views(12699)  Comments(4Edit  收藏  举报