2009-08-15 10 views
16

WCFを使用して通信するクライアント/サーバーアプリケーションがあり、NetDataContractSerializerを使用してオブジェクトグラフをシリアル化します。SOAPメッセージではなく、バイナリ形式でWCFメッセージをシリアル化します。

サーバーとクライアントの間で多くのデータが転送されるため、データメンバのサイズを微調整することでサイズを縮小しようとしました(intをshort、intにlongなどに変更しました)。

チューニングが終了したら、転送されたデータの量は変更されていないことがわかりました。
問題は、NetDataContractSerializerがオブジェクトグラフをXMLにシリアル化するため、データメンバのサイズに関係なく、その値のサイズだけが問題になります。たとえば、Int16データメンバの値10023は、10023(0x2727)ではなく、文字列 "10023"(0x3130303233)としてシリアル化されます。

Remotingでは、データメンバーのタイプに応じて値をシリアライズしたBinaryFormatterを使用できますが、WCFで使用できるかどうかわかりません。

誰かに解決策がありますか?

答えて

35

WCFはSOAPメッセージを使用しますが、どのようなメッセージエンコーディングが使用されているかは完全にあなた次第です。

基本的には、テキスト・エンコーディング(XMLメッセージのテキスト表現)またはバイナリ・エンコーディングの2つがあります。本当に必要であり、必要がある場合は、独自のメッセージエンコーディングを書くことができます。

デフォルトでは、basicHttpバインディングとwsHttpバインディングはテキストエンコーディングを使用しますが、必要に応じて変更することができます。 netTcpバインディング(企業ファイアウォールの背後にある明確な選択肢)は、デフォルトでバイナリを使用します。

ご希望の場合は、また、(単に設定で)独自の「バイナリのhttp」プロトコルを定義することができます。その後、

<bindings> 
     <customBinding> 
     <binding name="BinaryHttpBinding"> 
      <binaryMessageEncoding /> 
      <httpTransport /> 
     </binding> 
     </customBinding> 
    </bindings> 

とあなたのサービスとクライアント側の設定でそれを使用します。

<services> 
     <service name="YourService"> 
     <endpoint 
      address="http://localhost:8888/YourService/" 
      binding="customBinding" 
      bindingConfiguration="BinaryHttpBinding" 
      contract="IYourService" 
      name="YourService" /> 
     </service> 
    </services> 

これで、httpベースのトランスポートプロトコルが導入され、コンパクトバイナリ形式でメッセージがエンコードされます。

追加のコーディングや面倒なハックや手動のXMLシリアル化コードがたくさん必要になることはありません。一緒に接続して使用するだけです。ああ、WCFの柔軟性の喜び!

+0

?シリアライゼーション時間が短縮されるのか、それとも単にメッセージサイズが縮小されるのでしょうか? –

+0

このカスタムバインディングと、名前付きパイプトランスポートでbinaryMessageEncodingを使用しました。メッセージは、WCFテストクライアントと同様に、トレースリスナーのメッセージログごとに引き続きXMLエンコーディングです。私は100%自信がありません。これらは、生のメッセージを取るのではなく、ログを記録するオブジェクトのXMLシリアル化を自分で行っていないと確信しているわけではありません。 WCFでは、生の要求/応答とWebAPIを簡単に扱うことが難しくなります。 – AaronLS

+0

この回答は参考になりますが、バイナリエンコーディングは、メッセージがどのように「ワイヤー上で」送信されるか、つまりシリアル化された後にのみ変化することに注意してください。これは確かにデータサイズを削減しますが、シリアライズ方法は変更されません。より良い結果を得るために、バイナリエンコーディングを圧縮と併用することができます。 –

6

最初に考えました。トランスポート圧縮を有効にしましたか?

データはどのくらい複雑ですか?通常のDataContractSerializer(つまり単純なオブジェクトツリー)で動作するものであれば、protobuf-netを使用することができます。これは、サービス契約上の追加の属性を経由してWCFをサポートする非常に効率的なバイナリシリアルライブラリである - 例えば:

[ServiceContract] 
public interface IFoo 
{ 
    [OperationContract, ProtoBehavior] 
    Test3 Bar(Test1 value); 
} 

[ProtoBehaviour]は、このメソッドの異なるシリアライザに入れ替えるものです)

しかし:

    それは各プロパティの数値タグを識別できるようにする必要があり
  • - のいずれかの追加の属性を経由して、あるいはそれが[DataMember(Order = x)]属性にOrderを使用することができます
  • 継承(あなたがそれを使用している場合)は、それはあなたが素敵なアセンブリの共有(「MEX」それを愛していない...)

を使用している場合、それはまたで働く最高の作品

  • 特別な属性が必要ですMTOMを使用して、大きなメッセージのベース64コストを削減します。

  • 1

    バイナリエンコーダは、シリアル化とはまったく関係ないため、オブジェクトをバイナリでシリアル化しません。これは下位レイヤーで動作し、サーバーとクライアントの間でメッセージがどのように転送されるかを決定します。

    つまり、オブジェクトはまずDataContractSerializerによってシリアル化され、次にBinaryEncoderによってエンコードされます。したがって、DataContractSerializerが関与している限り、オブジェクトは常にXML形式になります。

    あなたはよりコンパクトなデータとより良いパフォーマンスをしたい場合は、このブログを読んで:ここで

    https://blogs.msdn.microsoft.com/dmetzgar/2011/03/29/protocol-buffers-and-wcf/

    1

    がここにカスタムエンコーディングを作成する方法の例ですhttps://www.codeproject.com/Articles/434665/WCF-Serialization-A-Case-Study

    それが実際にその何注目に値しますあなたがデフォルトのエンコーディングでbyte []を送るサービスメソッドを持っていた場合と同じです。ワイヤを経由するメッセージは、シリアル化の設定方法に関係なく、SOAP XMLエンベロープを使用します。

    それは次のようになりますので、バイナリのメッセージエンコードが大幅なパフォーマンスの向上を提供しない

    POST http://127.0.0.1:12345/forSwerGup182948/Client HTTP/1.1 
    Content-Type: text/xml; charset=utf-8 
    VsDebuggerCausalityData: uIDPo+WkoDpet/JOtGlW+EHdpDQAAAAAvFs5XOJ0tEW0wTvNVRDUIiabR6u+p+JNnd5Z+SWl1NcACQAA 
    SOAPAction: "http://tempuri.org/ITransmissionService/SendData" 
    Host: 127.0.0.1:12345 
    Expect: 100-continue 
    Accept-Encoding: gzip, deflate 
    Content-Length: 2890 
    
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><SendData xmlns="http://tempuri.org/"><message>eyI8Q2FsbGJhY2tJZD5rX19CYWNraW5nRmllbGQiOiJlYTQ3ZWIzMS1iYjIzLTRkODItODljNS1hNTZmNjdiYmQ4MTQiLCI8RnJvbT5rX19CYWNraW5nRmllbGQiOnsiPENoYW5uZWxOYW1lPmtfX0JhY2tpbmdGaWVsZCI6Ikdyb3VwMSIsIjxOYW1lPmtfX0==</message></SendData></s:Body></s:Envelope> 
    
    関連する問題