この話題はあちこちで議論されていますが、本当に正確な答えはありません。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 を調べて、構成を変更したくなかったので、カスタム バインドを作成しませんでした。
誰かがこの問題の正確な解決策を持っていますか?
この長い質問の説明を読んでいただきありがとうございます。
そして、提案された解決策を前もって感謝します。