C# – How to write a flexible messaging structure for sending TCP messages to clients and server

ctcp

The general question: how can I write a flexible, but not property heavy, messaging structure for sending TCP messages to clients and server?

Example:

I have a TCP Server for a game that sends some messages through TCP sockets to clients:

  1. Chat messages, including chat text, chat room, and speaker.

  2. Game messages, including game actions and events

  3. Client messages, including clients connecting, logging in, and disconnecting

To achieve this, when one of these actions occurs within the program, an event handler is called generating some specific event type.

ChatEvent with ChatEventArgs
GameEvent with GameEventArgs
ClientEvent with ClientEventArgs

These all extend the EventArgs class.

Now to my question. As things get more complex, I begin to cram more pieces of info into these EventArgs. My GameEventArgs start as

GameEventArgs gameArgs = new GameEventArgs(GameAction.Start);
gameArgs.gameId = "gameId123";
gameArgs.turn = "thisPlayersTurn";
JSON json = GameEventArgs.ToJson(gameArgs);
SendMessageToClient(json);

From this you can gather that GameEventArgs has some public properties such as gameId and turn. But a game is more than IDs and Turns. The client will need to receive game actions, which can be very complex. Suddenly the GameEventArgs needs more and more properties. This is fine, except, that only a few of these properties will be sent at a time. There could be 20-40 unused properties of GameEventArgs. Should I make more classes that inherit GameEventArgs, and only contain certain properties? I will be sending messages often, and I want to take the GC into consideration, as these messages are one time uses. (Should they then be IDisposable?).

Is there a better method to go about creating a messaging structure, where only a few of the defined properties of the message will be used at one time?

Best Answer

This problem has been solved very elegantly by Google, in their protocol buffers project. It has some issues that you need to be comfortable. It is a binary format. The sender and receiver need to agree on the message type being transferred (but not the message type version), and last time I checked the C# implementations were not Google implementations (or followed their API style).

However, the plus of having a light weight (both bytes and CPU) message format, that copes well with out of version sync client/servers and has a lot of features by default for message specifications are a winner for me.

Related Topic