2013-07-10 144 views
2

這個問題在這裏討論很多,但沒有答案是真的準確。 我有一個wcf服務,我用nettcpbinding創建。 我想檢查服務器和客戶端之間傳輸的消息大小/發送數據速率/接收數據速率。 該服務是一個雙工通道,客戶端代碼是通過添加服務引用自動生成的。 這兩個應用程序(客戶端/服務器)均使用C#.Net 4.0編寫。 的nettcp綁定使用默認的二進制編碼器和服務器端的配置設置如下:WCF tcp綁定消息的大小

<bindings> 
    <netTcpBinding> 
    <binding name="largeMessage" 
      receiveTimeout="infinite" 
      sendTimeout="24:00:00" 
      openTimeout="00:00:10" 
      closeTimeout="00:00:10" 
      maxReceivedMessageSize="2147483647" 
      maxBufferSize="2147483647" 
      maxConnections="2000" 
      transactionFlow="false" 
      listenBacklog="2147483647" 
      maxBufferPoolSize="2147483647"> 
     <readerQuotas maxDepth="128" 
      maxArrayLength="200000000" 
      maxStringContentLength="2147483647"/> 
     <security mode="None" /> 
     <reliableSession enabled="false" ordered="true" inactivityTimeout="infinite" /> 
    </binding> 
    </netTcpBinding> 
</bindings> 

服務是自託管,並通過創建開始作爲一個控制檯應用程序:

ServiceHost host = new ServiceHost(serviceObject, addresses); 

我用wireshark獲得一般統計數據和傳輸的TCP數據包,我看到我有一個非常高的數據速率。 所以我想檢查在客戶端和服務器之間傳輸的每個消息大小。 爲此,我使用了幾種技術來測量在本論壇中建議的消息大小,但沒有一個給出與wireshark完全相同的大小。

我已經測試了以下: WCF - Measuring approximate message sizes programmatically

此鏈接: http://winterdom.com/2009/07/comparing-text-and-binary-serialization-in-wcf/

,並在我的代碼這樣做:

static byte[] SerializeToBin<T>(T obj) 
    { 
     Message msg = ObjectToMessage(obj); 
     MessageEncodingBindingElement mebe = new BinaryMessageEncodingBindingElement(); 
     mebe.MessageVersion = MessageVersion.Soap12; 
     return Serialize(msg, mebe.CreateMessageEncoderFactory()); 
    } 

    static byte[] Serialize(Message msg, MessageEncoderFactory factory) 
    { 
     MessageEncoder enc = factory.Encoder; 
     MemoryStream stream = new MemoryStream(); 
     enc.WriteMessage(msg, stream); 
     return stream.ToArray(); 
    } 

    static Message ObjectToMessage<T>(T obj) 
    { 
     DataContractSerializer ser = new DataContractSerializer(typeof(T)); 
     return Message.CreateMessage(MessageVersion.Soap12, "", obj, ser); 
    } 

它不給準確的結果。

然後我試圖添加一個消息檢查,並聽取了前/後 - 發送/接收郵件作爲本文 http://devlicio.us/blogs/derik_whittaker/archive/2011/02/03/how-to-intercept-a-wcf-message-to-track-message-size.aspx 中建議,並調用此函數:

private void DetermineAndLogMessageDiagnostics(ref Message message, eMessageDirection messageDirection) 
    { 
     long sizeInBytes = 0; 
     var mb = message.CreateBufferedCopy(int.MaxValue); 
     message = mb.CreateMessage(); 

     var ms = new MemoryStream(); 
     using (var memWriter = XmlDictionaryWriter.CreateBinaryWriter(ms)) 
     { 
      mb.CreateMessage().WriteMessage(memWriter); 
      memWriter.Flush(); 
      sizeInBytes = ms.Position; 
     } 

     //Recalculates the updated average and updates the variables 
     //sentBytes, averageSentbps, receivedBytes, averageReceivedbps 
     RecalculateAverage(bodySizeInBytes, messageDirection); 
     Logger.Info("Message '{0}' size: {1} bits/{2} bytes. ({3} KBits). Sent (Total: {4} Bytes, {5:0.00} bps). Received (Total: {6} Bytes, {7:0.00} bps)", 
      action, 
      sizeInBytes * 8, 
      sizeInBytes, 
      ((double)sizeInBytes * 8)/1024, 
      sentBytes, 
      averageSentbps, 
      receivedBytes, 
      averageReceivedbps 
      ); 
    } 

這也不會給出準確的結果。 當我說不準確 - 我的意思是大約300-500字節的差異。但差距並非一成不變。

我不想創建自定義綁定,因爲我想檢查netTcpBinding並且不想更改任何配置。

有沒有人有這方面的準確解決方案?

感謝您閱讀這篇長長的問題描述。

並提前感謝任何建議的解決方案。

回答

1

您可以準確測量郵件大小的唯一方法是使用自定義郵件編碼器。它可以換原來的編碼器,並在該點(在調用WriteMessageReadMessage你可以看一下消息的大小。

你不使用二進制作家因爲寫的消息流得到準確的結果NetTcpBinding使用的二進制編碼器使用一些dictionaries在傳輸過程中進一步壓縮消息。

+0

[link](http:// zamd。net/2008/08/15/calculate-wcf-message-size /) – sattias

+0

正如我所說的那樣,在您的問題中以及鏈接建議中的轉儲消息不會使用即使寫入時也能壓縮消息的字典二進制格式。你真的需要一個自定義的編碼器。 – carlosfigueira

+0

謝謝。你的意思是我需要編寫一個CustomBinding來創建我的CustomEncoder嗎?如果我創建一個CustomBinding,我希望它具有與netTcpBinding相同的配置。這可以做到嗎? – sattias