我有一个基于JSON和POST方法的WCF Web服务,它有一个名为website的函数,返回一个包含2KB内容的JSON。此服务每秒有超过10K的请求。所以,我有很多文本数据要通过网络和I / O传递。我想我可以通过自动压缩响应来减少这个数据量。我知道通过在客户端设置标头来接受压缩内容,客户端可以通知服务器压缩内容是可接受的。但服务器如何发送压缩内容?
我已阅读this链接并实施它。但它仅适用于基于xml而非JSON的SOAP。我的意思是这个配置:
<customBinding>
<binding name="BinaryCompressionBinding">
<binaryMessageEncoding compressionFormat="GZip"/>
<httpTransport />
</binding>
</customBinding>
无法使用JSON,因为我们必须使用binaryMessageEncoding
,因为JSON需要webMessageEncoding
而且它不支持compressionFormat
。
另外,IIS动态压缩也无法帮助我。我添加了压缩JSON所需的标记。
更新 这是我的applicationhost.config:
<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="0"> <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> <dynamicTypes> <add mimeType="application/json" enabled="true" /> <add mimeType="application/json; charset=utf-8" enabled="true" /> </dynamicTypes> </httpCompression>
答案 0 :(得分:2)
作为替代方案和更多控制,您可以使用Message Inspector中的c#代码手动压缩您的回复。
对于WebApi,我使用委托处理程序做了类似的事情。您可以将我的代码包装到WCF的 Message Inspector 中。
Compress WebApi Response using delegating handler
或者使用IIS级压缩添加
<add mimeType="application/json; charset=utf-8" enabled="true" />
在您的applicationhost.config上。 See about json compression enabled mime type here
<强>更新强> 特别感谢@AnestisKivranoglou,我成功地为WCF的Json响应实现了gzip压缩。为了使@AnestisKivranoglou的答案更准确,我想在他的答案中添加一些细节。
您必须更改AfterReceiveRequest
的{{1}}和BeforeSendReply
,如下所示:
Message Inspector
这两段代码可以让您知道客户是否可以接受object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext)
{
try
{
var prop = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
var accept = prop.Headers[HttpRequestHeader.AcceptEncoding];
if (!string.IsNullOrEmpty(accept) && accept.Contains("gzip"))
{
var item = new DoCompressExtension();
OperationContext.Current.Extensions.Add(item);
}
}
catch { }
return null;
}
void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState)
{
if (OperationContext.Current.Extensions.OfType<DoCompressExtension>().Count() > 0)
{
HttpResponseMessageProperty httpResponseProperty = new HttpResponseMessageProperty();
httpResponseProperty.Headers.Add(HttpResponseHeader.ContentEncoding, "gzip");
reply.Properties[HttpResponseMessageProperty.Name] = httpResponseProperty;
}
}
!因此,您实现了gzip
,可以在回复之前和接收之后捕获请求。现在,您需要使用this link实施behaviorExtensions
。请注意,您必须使用this link解决bindingElementExtensions
问题。最后,下面列出了一些变化:
GZip
功能: ApplyConfiguration
case "webMessageEncoding":binding.innerBindingElement = new WebMessageEncodingBindingElement();break;
更改为innerMessageEncoding="textMessageEncoding"
。如果没有遗漏任何内容,您可以使用innerMessageEncoding="webMessageEncoding"
方法检查并致电该服务,如果您在请求的标头中添加Post
,则Json
会收到压缩响应。如果您不添加此标题,您将收到未压缩的正常响应。