Over a million developers have joined DZone.

Easy and Performant Client/Server Communication with protobuf-net & Griffin.Framework

DZone's Guide to

Easy and Performant Client/Server Communication with protobuf-net & Griffin.Framework

· Agile Zone ·
Free Resource

Adopting a DevOps practice starts with understanding where you are in the implementation journey. Download the DevOps Transformation Roadmap. Brought to you in partnership with Techtown.

ProtoBuf is Googles open serialization format which can be used to serialize objects in a standardized way. With it, different platforms can communicate with a format that is much more efficient than XML. Combine the most popular implementation if it, protobuf-net, with Griffin.Framework and you get an easy and fast way of sending information between processes.

(this is a follow up on my previous post)

As I know that the format is quite efficient I felt that it would be a powerful combination. I’ve therefore created a simple client/server where I made a benchmark for how long it would take for a Griffin.Framework client to send 20 000 messages to a Griffin.Framework server. The requirement was that the client have to receive the reply before sending the next message. To spice everything up I changed so that the client application used 20 clients simultaneously, and all clients had to receive all replies before the time was stopped.

As MicroMsg sends the type over the network it works well together with protobuf-net (which requires a specific type to be able to deserialize the message),

Both the server and client was running on the same machine.

The message

The message being transferred and it’s reply looked like this:

public class Authenticate
    public string UserName { get; set; }

    public string Password { get; set; }

public class AuthenticateReply
    public bool Success { get; set; }

    public string Decision { get; set; }

The serializer

To start with, I had to write a serializer for the library which uses protobuf.

class ProtoBufSerializer : IMessageSerializer
    static ConcurrentDictionary<string, Type> _types = new ConcurrentDictionary<string, Type>();

    public void Serialize(object source, Stream destination, out string contentType)
        Serializer.NonGeneric.Serialize( destination, source);
        contentType = "application/protobuf;" + source.GetType().FullName;

    public object Deserialize(string contentType, Stream source)
        Type type;
        if (!_types.TryGetValue(contentType, out type))
            int pos = contentType.IndexOf(";");
            if (pos == -1)
                throw new NotSupportedException("Expected protobuf");

            type = Type.GetType(contentType.Substring(pos + 1), true);
            _types[contentType] = type;
        return Serializer.NonGeneric.Deserialize(type, source);

As you can see, I also use a Type cache as Type.GetType() is terrible slow, even thought it has a built in cache. You could implement a JSON or Xml serializer in the same way.

The server

As a server you typically just create a ChannelTcpListener:

var settings = new ChannelTcpListenerConfiguration(
    () => new MicroMessageDecoder(new ProtoBufSerializer()),
    () => new MicroMessageEncoder(new ProtoBufSerializer())

var server = new MicroMessageTcpListener(settings);
server.MessageReceived = OnServerMessage;

server.Start(IPAddress.Any, 1234); 

That’s it, all you need now is a callback to receive messages from all clients:

private static void OnServerMessage(ITcpChannel channel, object message)
    var auth = (Authenticate) message;
    channel.Send(new AuthenticateReply() {Success = true});

How much code/configuration would you need in WCF to achieve the same thing?

The client

In the client you do about the same, but you use async/await instead of a callback.

private static async Task RunClient()
    var client = new ChannelTcpClient<object>(
        new MicroMessageEncoder(new ProtoBufSerializer()),
        new MicroMessageDecoder(new ProtoBufSerializer())

    await client.ConnectAsync(IPAddress.Parse(""), 1234);

    for (int i = 0; i < 20000; i++)
        await client.SendAsync(new Authenticate { UserName = "jonas", Password = "king123" });
        var reply = (AuthenticateReply)await client.ReceiveAsync();

        if (reply.Success)
            //Console.WriteLine("Client: Yay, we are logged in.");
            //Console.WriteLine("Client: " + reply.Decision);

    await client.CloseAsync();

The result

If you study the screenshot, you will see that Griffin.Framework only takes 28% of the total time for those messages. 37% of the time is used by protobuf-net. The remaining 35% is spent in .NET/Windows.

On my machine that means that 800 000 .NET objects (400 000 requests and 400 000 replies) where transferred in 11 seconds time. That’s 0,01398375 milliseconds per object. Those digits are not as important as the fact that Griffin.Framework only took 28% of the time being used by the application.

Take Agile to the next level with DevOps. Learn practical tools and techniques in the three-day DevOps Implementation Boot Camp. Brought to you in partnership with Techtown.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}