alzaimar
alzaimar

Reputation: 4622

What is the most compact wcf binding in terms of total bytes transferred?

We need to create a WCF service for a low bandwidth network. So our goal is to create the binding configuration which produces the smallest number of bytes per call. This is an excerpt from the app.config

<customBinding>
   <binding name="binaryBinding">
     <binaryMessageEncoding/>
     <tcpTransport />
   </binding>
</customBinding>

I assume that setting up a connection introduces overhead as well, so we would keep that to a minimum. A typical scenario would be

Client.Connect();
while (!userTerminates())
{
  var Response = Client.DoSomething(parameters);
  <user input>
  var anotherResponse = Client.DoSomethingElse(otherParameters);
}
Client.Close();

The data being sent/received varies from some 20 bytes to a couple of 100.

So far I managed to setup WCF to use netTcpBinding and binary encoding, but I still have an overhead of 400%. I sent a single string of 600 chars and received 2200. I measured this by using a MessageInspector which measures the length of incoming and outgoing messages. I assume that the overhead comes from the SOAP messages. Edit: Maybe my measuring is wrong.

I also understand that I can compress the communication as shown in the WCF Sample library. GoogleProtocol also seems an option.

But I want to start from the beginning: How can I modify the configuration (or eventually create my own protocol) to minimize the total bytes sent. Security is not an issue at this time, neither is performance, it's only the number of bytes being sent/received I am interested in.

Thanks for any hints.

Upvotes: 2

Views: 295

Answers (2)

Marc Nijweide
Marc Nijweide

Reputation: 11

The overhead is caused by the fact that WCF serializes objects as XML streams. This means it makes no assumptions about the order or format of the fields it serializes and needs to provide this information with the message. The binary message encoders use the XmlDictionaryReader/Writer to serialize messages and use dictionaries to look up fields that have been transmitted earlier in the session. Still, at some point this information is communicated between client and server which causes extra bytes to be transmitted depending on the size of your data contract.

To reduce payload, consider writing your own serializer as shown here: http://www.codeproject.com/Articles/434665/WCF-Serialization-A-Case-Study.

Also you may consider packaging your data in a single field prior to serialization in the OnSerializing and OnDeserialized methods like so:

[DataContract]
public class Data
{
    [DataMember]
    private byte data;

    private bool bool1;
    private bool bool2;

    [OnSerializing]
    internal void OnSerializing()
    {
        data = Convert.ToByte((bool1 ? 0 : 1) & (bool2 ? 0 : 2));
    }

    [OnDeserialized]
    internal void OnDeserializing()
    {
        bool1 = (Convert.ToInt32(data) & 1) != 0;
        bool2 = (Convert.ToInt32(data) & 2) != 0;
    }
}

Upvotes: 1

CodeCaster
CodeCaster

Reputation: 151584

You're right in that netTcp uses SOAP, which may indeed cause your 20 bytes payload to inflate to more than that.

How to apply a custom binding is explained in CodeProject: CompactMessageEncoder . If the payload is object-like and you don't call many difference methods, Google's Protocol Buffers and a custom framing protocol over sockets.

Upvotes: 2

Related Questions