如何减少WCF soap消息大小以节省带宽?

时间:2013-01-23 08:53:45

标签: c# wcf service bandwidth

我编写了一个MessageSizeInspector类来检查服务从客户端收到的消息的大小。这是它的样子:

//the actual implementation logs more!
//but in this question, my only concerns is request.ToString()
public sealed class MessageSizeInspector : 
            BehaviorExtensionElement,   //to enable it to be used in config
            IDispatchMessageInspector,  //service-side inspector
            IEndpointBehavior           //so we can apply it on endpoint
{
   if (request != null )
   {
      Logger.Verbose("Message = {0}\n", request.ToString()));
   }       
   //more  
}

并记录此格式的消息:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://localhost:8961/EngineService</To>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/IEngineService/GetMousePatternID</Action>
  </s:Header>
  <s:Body>
    <GetMousePatternID xmlns="http://tempuri.org/">
      <args>
        <accelerator xmlns="http://schemas.datacontract.org/2004/07/Runaware.Insight.EngineService" />
        <accessKey xmlns="http://schemas.datacontract.org/2004/07/Runaware.Insight.EngineService" />
        <controlId xmlns="http://schemas.datacontract.org/2004/07/Runaware.Insight.EngineService">66222</controlId>

        <!--- deleted the rest to avoid verbosity -->

      </args>
    </GetMousePatternID>
  </s:Body>
</s:Envelope>

正如您所看到的,实际消息是 tiny ,但XML元素和命名空间使其太大。特别是,与实际消息相比,命名空间太大了。

我的问题是:我们如何减少 soap 消息的大小?由于xmlns对于所有元素都相同,因此WCF可以对此进行优化,但事实并非如此。我们可以使用我们选择的更短的命名空间吗? acceleratoraccessKey之类的元素很少甚至没有任何价值(正如您可以通过向右滚动看到的那样),但它们仍然存在!我们可以让WCF省略它们并在服务端假设它们的值null(或默认值)吗?

简而言之,我们可以采取哪些措施来节省带宽?

我假设上面的消息是客户端,完全采用相同的格式,具有相同的XML元素和命名空间。

服务器使用C#和WCF编写,客户端使用Windows Web Services API以C ++编写。服务和客户都是我写的。所以我完全控制了它们。如果需要,我可以更改它以节省带宽!

4 个答案:

答案 0 :(得分:2)

除了其他人已经说过的东西(例如:WCF压缩)......

尝试在DataContracts,DataMembers以及ServiceContracts上设置名称和命名空间。

示例:

 [DataContract(Name = "a", Namespace = "")]
 class Person
 {
     [DataMember(Name = "a")]
     public string FullName;
     [DataMember(Name = "b)]
     public int Age;
 }

这将使Person被称为&#34; a&#34;来自命名空间&#34;&#34;并将属性FullName称为&#34; a&#34;,使XML缩短为:

<a> -- Represents the Person class
    <a>Name of the person</a> -- Represents the FullName property
    <b>38</b>
</a>

属性和类必须有不同的&#34;短&#34;来自DataContract和DataMembers的名称。

参考:https://bkiener.wordpress.com/2010/05/04/optimize-data-contracts-for-better-wcf-performance/

答案 1 :(得分:1)

嗯,我的第一个方法是使用WCF Compression。我只能给你链接,因为我没有经验。但我认为,这将是一个相当不错的改进。

问题是,你对客户有影响吗?因为它的配置也必须进行编辑。

编辑:您的一条评论中回答了问题。 :O)

答案 2 :(得分:1)

欢迎使用SOAP和许多人遇到无知的问题。 XML也很好,也是SOAP,但是有一个基于文本的表达系统的开销。带宽受到打击很大,特别是对于小消息。

这不是你可以做的很多 - 在IIS中进行外部压缩,然后删除soap / xml并使用JSON转到web api。 web servviec / soap标准非常明确,也是标准。绕过它(掉落要求,使用别的东西)是真正处理它的唯一方法。

答案 3 :(得分:0)

由于您可以完全控制所有内容,为什么不改为使用WebAPI呢?

在做出最终决定之前,请先查看此问题:Do I need WCF if I can use ASP.net Web API