2

この話題はあちこちで議論されていますが、本当に正確な答えはありません。nettcpbinding で作成した wcf サービスがあります。サーバーとクライアントの間で転送されているメッセージ サイズ/送信データ レート/受信データ レートを調べたいと思いました。サービスは二重チャネルであり、クライアント コードはサービス参照を追加することによって自動生成されます。どちらのアプリケーション (クライアント/サーバー) も C# .Net 4.0 で記述されています。デフォルトのバイナリ エンコーダーとサーバー側の構成設定を使用する nettcp バインディングは次のとおりです。

<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 - プログラムによるおおよそのメッセージサイズの測定

このリンク: 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-で提案されているように、Before/After - Send/Receive メッセージをリッスンしようとしました 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 を調べて、構成を変更したくなかったので、カスタム バインドを作成しませんでした。

誰かがこの問題の正確な解決策を持っていますか?

この長い質問の説明を読んでいただきありがとうございます。

そして、提案された解決策を前もって感謝します。

4

1 に答える 1

1

メッセージ サイズを正確に測定する唯一の方法は、カスタム メッセージ エンコーダーを使用することです。元のエンコーダーをラップすることができ、その時点で (への呼び出しでWriteMessageReadMessageメッセージのサイズを確認できます。

バイナリ ライターを使用してメッセージをストリームに書き込んでも、正確な結果は得られません。これは、 で使用されるバイナリ エンコーダーNetTcpBindingがいくつかの辞書を使用して、送信中にメッセージをさらに圧縮するためです。

于 2013-07-10T17:53:09.667 に答える