2009-08-15 9 views
16

Ho un'applicazione client-server, che comunica usando WCF, e utilizza NetDataContractSerializer per serializzare il grafico degli oggetti.Serializzare il messaggio WCF in modo binario e non come messaggio SOAP

Dal momento che molti dati vengono trasferiti tra il server e il client, ho provato a ridurne le dimensioni sintonizzando le dimensioni dei membri dei dati (ad esempio, cambiato int in short, long in int, ecc.).

Dopo aver terminato la messa a punto, ho scoperto che la quantità di dati trasferiti non è cambiata!
Il problema è che NetDataContractSerializer serializza il grafico degli oggetti in XML, quindi, indipendentemente dalle dimensioni del membro dei dati, l'unica cosa che conta è la dimensione del suo valore. Ad esempio, il valore 10023 di un membro dati Int16 verrà serializzato come stringa "10023" (0x3130303233), anziché solo 10023 (0x2727).

Mi ricordo che in Remoting potrei usare il BinaryFormatter che serializzato i valori a seconda del tipo di membro di dati, ma non so se è possibile utilizzarlo con WCF.

Qualcuno ha una soluzione?

risposta

35

WCF utilizza i messaggi SOAP, ma quale tipo di codifica dei messaggi viene utilizzato, dipende totalmente da voi.

Fondamentalmente, out of the box, si dispone di due: codifica del testo (rappresentazione del testo del messaggio XML) o codifica binaria. Puoi scrivere la tua codifica personale, se davvero devi e devi.

Fuori dalla scatola, i collegamenti di base HTTP e wsHttp utilizzano la codifica del testo - ma è possibile cambiarlo se lo si desidera. Il binding netTcp (che è la chiara scelta preferita dietro i firewall aziendali) utilizzerà binario per impostazione predefinita.

È inoltre possibile definire (solo in config) il proprio protocollo "binario http", se lo si desidera:

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

e poi usarlo nel vostro servizio e lato client config:

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

Ora disponi di un protocollo di trasporto basato su http, che codificherà il tuo messaggio in formato binario compatto, che potrai utilizzare e divertirti!

Nessun codice aggiuntivo o hack incasinati o un sacco di codice di serializzazione XML manuale necessario: basta collegarlo e usarlo! Ah, la gioia della flessibilità della WCF!

+0

così fa la codifica dei messaggi binario offrono un miglioramento significativo delle prestazioni? Il tempo di serializzazione è ridotto o la dimensione del messaggio è ridotta? –

+0

Ho usato questo bind personalizzato e binaryMessageEncoding con il trasporto di pipe denominato, e i messaggi sono ancora codifica XML come da log dei messaggi nel listener di traccia e WCF Test Client. Non sono sicuro al 100% che questi non stiano facendo la loro serializzazione XML degli oggetti per registrarli invece di prendere il messaggio non elaborato. WCF rende così difficile collegarsi alla richiesta/risposta grezza rispetto a WebAPI che lo rende facile. – AaronLS

+0

Questa risposta è utile, ma tieni presente che la codifica binaria cambia solo il modo in cui il messaggio viene inviato "sul filo", ossia dopo che è stato serializzato. Mentre questo certamente riduce la dimensione dei dati, non cambia il metodo di serializzazione. La codifica binaria può essere utilizzata con la compressione per risultati migliori. –

6

Primo pensiero; hai abilitato la compressione di trasporto?

Quanto sono complessi i dati? Se è qualcosa che funziona con il normale DataContractSerializer (cioè un albero di oggetti semplice), allora protobuf-net potrebbe essere utile. Si tratta di una libreria molto efficiente binari serializzazione con il supporto per WCF tramite attributi aggiuntivi sul contratto di servizio - ad esempio:

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

(il [ProtoBehaviour] è quello che scambia nei diversi serializzatore per questo metodo)

Tuttavia:

  • ha bisogno di essere in grado di identificare un tag numerico per ogni proprietà - attraverso attributi extra, oppure può utilizzare il Order su un attributo [DataMember(Order = x)]
  • eredità (se lo si utilizza) richiede attributi extra
  • funziona meglio se si utilizza la condivisione di montaggio ("mex" non amarla ...)

Bene, funziona anche con MTOM, riducendo il costo di base 64 per i messaggi più grandi.

1

Il codificatore binario NON serializzerà il tuo oggetto in binario, perché non ha nulla a che fare con la serializzazione! È qualcosa che funziona a un livello inferiore e decide come il messaggio viene trasportato tra server e client.

In altre parole, l'oggetto verrà prima serializzato (da DataContractSerializer, ad esempio) e quindi codificato (da BinaryEncoder). Quindi il tuo oggetto sarà sempre in formato XML purché sia ​​coinvolto DataContractSerializer.

Se si desidera un data più compatto e migliori prestazioni, leggere questo blog:

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

1

Ecco un esempio di come fare la codifica personalizzata qui https://www.codeproject.com/Articles/434665/WCF-Serialization-A-Case-Study

Vale la pena notare che ciò che in realtà viene inviato è lo stesso come se si avesse un metodo di servizio che invia byte [] con la codifica predefinita. Il messaggio in corso sul cavo utilizza ancora una busta XML SOAP indipendentemente dalla modalità di configurazione della serializzazione.

Ecco come si presenta:

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> 
Problemi correlati