This week's book giveaway is in the OCPJP forum. We're giving away four copies of OCA/OCP Java SE 7 Programmer I & II Study Guide and have Kathy Sierra & Bert Bates on-line! See this thread for details.
I'm writing a server that implements a turn based card engine, that's to say it implements a protocol, handling client requests, running the game, keeping track of the state and prompting the clients to act.
Its using sockets and so I've got a rather ugly looking solution with plenty of ifs, threads and so on. Clients also have to implement their side of the protocol.
Is there a standard way to do this kind of communication, I was wondering if messaging approach like JMS would be neater? I'm thinking an event based solution would be neat, the client kind of responds to a message rather than sitting in a loop waiting for the socket's message to match the protocol prompt.
probably there is no standard way :-) here are some ideas...
- you could start to refactor your server so it uses less if/else (strategy/action/command pattern). e.g. one thread reads bytes from socket, transforms them to action objects and puts them in a queue. other thread executes actions and puts response in output queue. like this your game is decoupled from the network (you could use simle java method calls to add actions to the queue) - or you could look into various remote invocation protocols (rmi/hessian/...) - or you could look into the java.nio packets which allow you to imlement event driven io - or you could look into JGroups which makes it easy for you to communicate with a group (e.g. replicated HashMaps and thelike) - (or a combination of above) - JMS might be overkill for a turn based card game server... (it takes quite some effort and software to set it up) -
if you can show us some code, then we can give more concrete help.
Joined: Apr 19, 2006
Thanks for the hints, I'll have a look into those.
nio look interesting as does your idea of making a simple queue based system, I guess in this way you're mimicking JMS type functionality...
I forgot to mention the underlying protocol has already been set for me, its simple string based TCP.
Keep an eye on the thread if you like and I'll post some code / ideas as it develops. Part of why I'm doing this is to experiment with different techniques/designs so its kind of an academic exercise.
Joined: Jun 19, 2001
yes, it's kind of JMS for the poor :-) ... very poor.
but it also decouples your game from the network (you could write an AI that drops in actions in the queue and if you have a local GUI, then it can do the same...)
even if your protocol is fixed... you can stil create actions out of it...
this would extract your if/else logic into one place (an action factory). of course there are smarter aproaches to create the actions (e.g. a Map of command names and action classes + reflection )
be aware that the action pattern will result in many classes (at least if there are many commands your server understands.
i dont read the "Game Development" forum that often... but you can send me a message...
Joined: Apr 19, 2006
That's really interesting...
I'm working on the messaging part at the mo (kind of abstracting the protocol away and setting up an event based model - experiment stages at the moment but we'll see) but I like the action idea so will look into that too, it would certainly break out the functions.
My current thoughts are along the lines of a "message broker" that is threaded (gasp) and just listens for messages, when it gets a message it calls a method (onMessage()) on a message listener. That onMessage I'm thinking can handle the message, a single server would be 'listening' to all connections and so can handle state etc...
not sure if using Action classes in complimentary or to be used instead of the above... I'll think on...
I guess the Action would have a run() method and based on state that passed in, returns a new state?
usualy you namethe method "execute()" or something in this line (run() is from Runnable interface)
the command class needs references to your game (e.g. the stack of cards). depending on how you implement it you can pass the required references in when constructing the command or you can pass something generic as parameter when executing the command (e.g. execute(GameContext ctx) ). both has drawbacks: constructor -> you can not (easely) construct the command by reflection. parameter -> you need this generic "all you need is in here" object you can pass as parameter.
the onMessage (JMS :-) ) way sounds ok. you can implement it in several ways (since you mentioned its more of an academic example i keep emptying my head :-) ) either your "server thread" is a message producer where listeners can register. or you can still keep your server drop the messages in the queue and add another thread that polls (look at the java.util.Queue stuff if you are on java 1.5) the queue and fires events if there are messages in there (this would be some sort of a push-pull adapter, see JGroups)......