我使用很棒的 Scott Hanselman 文章在IIS上启用Dynamic Compression
:
在文章开头,他说:
在客户端,只需添加这样的代码很容易:
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
第一个问题是:我应该在哪里添加以上代码?
我正在使用BasicHttpBinding
,现在请考虑以下代码:
using (ServiceReference1.Srv1 client = new ServiceReference1.Srv1Client())
{
var data = client.GetData(string longText, byte[] file);
}
通过该代码,我从客户端应用程序调用我的服务。现在的问题是,如何使用GZIP
自动压缩客户端请求(每个参数),从而导致调用Web服务变得更快?
谢谢
答案 0 :(得分:1)
request.AutomaticDecompression属性位于HttpWebRequest对象上。 我不确定您是否使用WCF OData服务。根据Scott Hanselman的博客,这应该适用于WCF OData Service。
我猜BasciHttpBinding默认不支持压缩。这个想法来自this blog.
我将创建BehaviorExtensionElement,CompressionBehaviorSection,如下所示。
public class MessageCompressionBehavior : IDispatchMessageInspector, IServiceBehavior, IClientMessageInspector
{
}
public class CompressionBehaviorExtensionElement :BehaviorExtensionElement
{
}
<extensions>
<behaviorExtensions>
<add name="compression" type="yournamespace.CompressionBehaviorExtensionElement, yourassembly, Version=...., Culture=neutral, PublicKeyToken=......"/>
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehavior>
<compression />
</serviceBehavior>
</behaviors>
然后在基本Http绑定上应用此行为。
IDispatchMessageInspector和IClientMessageInspector将根据是发送还是接收数据来压缩/解压缩数据。
更新日期:2019年1月29日 我昨天发现了另一种方法:
步骤1:如果您的服务是IIS Hosted,则可以启用动态压缩模块。
然后在applicationHost.config中为SOAP消息添加mime类型,如下所示:
<add mimeType="application/soap+xml" enabled="true" />
<add mimeType="application/soap+xml; charset=utf-8" enabled="true" />
<add mimeType="application/soap+xml; charset=ISO-8895-1" enabled="true" />
第2步:自定义IWebRequestCreate
完成此操作后,您将必须使WCF通过HTTP请求发送“ Accept Encoding”标头。您可以如下所示创建自定义IWebRequestCreate
public class CompressibleHttpRequestCreator : IWebRequestCreate
{
public CompressibleHttpRequestCreator()
{
}
WebRequest IWebRequestCreate.Create(Uri uri)
{
HttpWebRequest httpWebRequest =
Activator.CreateInstance(typeof(HttpWebRequest),
BindingFlags.CreateInstance | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance,
null, new object[] { uri, null }, null) as HttpWebRequest;
if (httpWebRequest == null)
{
return null;
}
httpWebRequest.AutomaticDecompression = DecompressionMethods.GZip |
DecompressionMethods.Deflate;
return httpWebRequest;
}
}
第3步:更改客户端配置中的配置 然后,您可以在客户端的app.config或web.config中添加以下设置:
<system.net>
<webRequestModules>
<remove prefix="http:"/>
<add prefix="http:" type="WcfHttpCompressionEnabler.CompressibleHttpRequestCreator, WcfHttpCompressionEnabler,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</webRequestModules>
</system.net>
该解决方案的说明at this blog。它还具有示例代码at this link.
我希望这会为您的问题提供足够的帮助。
答案 1 :(得分:1)
这只是我的建议。
您可以定义自己的ClientMessageFormatter,DispatchMessageFormatter。
ClientMessageFormatter用于序列化请求和反序列化响应。
DispatchMessageFormatter用于反序列化请求和序列化请求。
如果您可以使用自己的CompressionAlgorithm通过Gzip或deflate序列化和反序列化请求和响应,则消息将变小。
这两个界面都有下面的方法。
public void DeserializeRequest(Message message, object[] parameters)
{
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
}
public object DeserializeReply(Message message, object[] parameters)
{
}
public Message SerializeRequest(MessageVersion messageVersion, object[] parameters)
{
}
要使用自己的ClientMessageFormatter和DispatchMessageFormatter,应使用EndpointBehavior。
在ApplyClientBehavior和ApplyDispatchBehavior中,应将ClientMessageFormatter设置为ClientOperation的Formatter属性,并将DispatchMessageFormatter设置为DispatchOperation的formatter属性。
此外,要启用动态compressionAlgorithm,最好将您的compressionAlgorithm传递给端点行为,然后该行为将compressionAlgorithm传递给ClientMessageFormatter和DispatchMessageFormatter,以便它可以知道要使用哪种压缩。
仍有许多事情要做,例如,如何使用wcf的默认ClientMessageFormatter和DispatchMessageFormatter结合您自己的ClientMessageFormatter和DispatchMessageFormatter对消息进行序列化和反序列化。
由于wcf的默认格式化程序用于序列化和反序列化请求和响应,因此您可以使用格式化程序在wcf序列化的基础上压缩消息。因此,在使用格式化程序之前,应在endpointbehavior的ApplyDispatchBehavior和ApplyClientBehavior中获得wcf的默认格式化程序。
然后将自己的格式化程序的some属性设置为wcf的默认属性,以便您可以使用wcf的默认格式化程序。
答案 2 :(得分:0)
请求压缩不是服务器或客户端理解的HTTP标准。为此,您必须自己在客户端和服务器上进行操作。
我已经有一段时间没有进行WCF开发了,但是我很确定WCF可以做到这一点。