Network Message Handling

Started by
3 comments, last by RobAU78 14 years, 5 months ago
Hi! I am engineering a MMO game server. I decided to use byte messages in prior to XML or JSON. The problem is that I can't figure out how to make a low coupled system. The message has the following structure: length:short, messageID:byte, data:mixed. When server receives a message, the messageHandler code looks like this: read(messageType); switch(messageType) { case login: readStringFromSocket(username); readStringFromSocket(password); tryToLogin(username,password); break; case logout: user = getSender(); tryToLogout(user); break; case ...: ... break; etc. } I have about a hundred message types, so the switch looks like a really long spaghetti. The other problem is that this code has a really high coupling. If I want to change network protocol to, for example, XML, I would have to rewrite a lot of message handling stuff. I guess it could avoid this by using observer pattern. So can you please share your thoughts about which is the best pattern/style/etc for handling messages and what do you use in situations like this?
Advertisement
First of all you should have your client into different stages, for example I have login, lobby and playing state in my own code.

With this you can split some of the events into the different states, however the playing state will probably contain most the events.
Check out the "Chain-of-responsibility pattern", it might help you:
http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

PS. And if that is your server code, I think you should read my experiences writing servers in languages like that. The read is called "For everyone who wants to make an MMO": http://www.gamedev.net/community/forums/topic.asp?topic_id=549713
My MMO game is a simple chess game, so I don't need an uber cool server, and the deadline is coming really fast. So I chose Java. The chain of responsibility patter wouldn't help me too much. Maybe someone can post an example of his own message handling code?
Thanks in advance!

[Edited by - elvman on October 8, 2009 7:52:09 PM]
Here's an option; java.util.Observer/Observable lets you implement an arbitrary publish/subscribe system.

This allows you to attach member methods to named "signals".

You can then have a giant switch statement, but one in which each case looks something like this;

switch(message.id)
{
case MYSIGNAL_DOTHIS: emit signal MySigDoThis(message);
}

This converts your integer ID into something in your class system, at which point you can do decent work with it.

At the other end of the system, when you create the various objects for the system, they subscribe to the messages they need to know about.

So, a chess game might have a "CBoard" object representing the state of the board. You probably want to attach "MySigResetGame" to CBoard::reset(Message) and then everytime the reset message arrives it'll be sent off to everyone who needs it -- You'll be able to attach multiple objects to multiple signals which means the knowledge about which signals something needs is inside the classes rather than all in the switch.

So, for example, the "AccountManager" might receive login and logout messages. On a successful login, they create a board object (which might contain the window) and it connects to the reset/movepiece messages so it can be updated. Logout will destruct the board. And so on. Note how this gets you a lot of state management for free -- your system will just ignore movepiece messages until a successful login.
This might be a moot point by now, but a relatively easy way to lower the coupling here is to use the Command pattern. Each message type would refer to an instruction or set of instructions for the server to execute. A map/dictionary object would hold the associations between message types and Command objects. Obviously, then, each Command object instantiated would need to be reentrant, so all message-specific state would need to be fed into it upon method execution. Furthermore, you'd need an interface or abstract base class for all Commands, and then a concrete subclass corresponding to each message type.

Hope this helps!

This topic is closed to new replies.

Advertisement