webservice传输数据量较大的情况的解决方案
目前遇到的项目服务器端是java平台的,客户端是.net的,而且网络情况不定,所以服务器端采用webservice方式向客户端提供数据。
这样的情况下传输数据的量就成为影响性能的瓶颈之一。
刚开始我们针对某些返回数据量较大的方法采用gzip压缩,那么在客户端直接进行解压缩,由于不是重点直接上方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/// <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;
}
/// 对内容进行解压缩
/// </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的内容:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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;
}
}
{
/// <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;
}
}