WCF 压缩 JSON 响应



>我有一个基于JSON和POST方法的WCF Web服务,它有一个名为website的函数,返回一个包含更多2KB内容的JSON。此服务每秒的请求数超过 10K。因此,我有很多文本数据要通过网络和I/O传递。我想我可以通过自动压缩响应来减少此数据量。我知道通过在客户端设置一个标头来接受压缩内容,客户端可以通知服务器压缩内容是可以接受的。但是服务器如何发送压缩内容呢?

我已经阅读了这个链接,并实现了它。但它仅适用于基于 xml 的 SOAP,而不适用于 JSON。我的意思是这个配置:

<customBinding>
<binding name="BinaryCompressionBinding"> 
<binaryMessageEncoding compressionFormat="GZip"/> 
<httpTransport /> 
</binding>
</customBinding> 

不能使用 JSON,因为我们必须使用binaryMessageEncoding,因为 JSON 需要webMessageEncoding并且不支持compressionFormat.

另外,IIS动态压缩也帮不了我。我添加了压缩 JSON 所需的标记。


更新:这是我的应用程序主机.config:

<httpCompression directory="%SystemDrive%inetpubtempIIS Temporary Compressed Files" minFileSizeForComp="0"> <scheme name="gzip" dll="%Windir%system32inetsrvgzip.dll" /> <dynamicTypes> <add mimeType="application/json" enabled="true" /> <add mimeType="application/json; charset=utf-8" enabled="true" /> </dynamicTypes> </httpCompression>

作为替代和更多的控制,您可以在消息检查器中使用 c# 代码手动压缩响应。

对于WebApi,我使用委派处理程序做了类似的事情。我认为您可以将我的代码包装到 WCF 的消息检查器中。

使用委派处理程序压缩 WebAPI 响应

邮件检查器

或者要使用 IIS 级别的压缩添加

<add mimeType="application/json; charset=utf-8" enabled="true" />

在您的应用程序主机上。 在此处查看有关启用 json 压缩的 MIME 类型的信息


更新:特别感谢@AnestisKivranoglou,我已经成功地为 WCF 的 Json 响应实现了 gzip 压缩。为了使@AnestisKivranoglou的回答更准确,我想在他的回答中添加一些细节。

你必须改变Message InspectorAfterReceiveRequestBeforeSendReply,比如波纹管:

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;                                
}            
}

这 2 段代码让您知道客户端是否可以接受gzip!因此,您实现了一个可以在回复之前和接收之后捕获请求的behaviorExtensions。现在,您需要使用此链接实现bindingElementExtensions。请注意,您必须使用此链接修复GZip问题。最后,下面列出了少量更改:

  1. 将项目添加到ApplyConfiguration函数:

case "webMessageEncoding":binding.innerBindingElement = new WebMessageEncodingBindingElement();break;

  1. 将自定义绑定从innerMessageEncoding="textMessageEncoding"更改为innerMessageEncoding="webMessageEncoding"

如果未遗漏任何内容,则可以使用Post方法检查和调用服务,并在将Accept-Encoding:gzip, deflate添加到请求标头时Json接收压缩响应。如果不添加此标头,您将收到未压缩的正常响应。

最新更新