Threads and Networking concepts and details

I’ve read up on the jME multithreading (as well as the links provided in that tutorial), and I’ve read the page about SpiderMonkey (also seen the MirrorMonkey thread) and I have some questions on how it all fits together.

My program will have 1 (at least 1, but possibly more in the future) “player”. This player gets status information (calculating location among other things) and sends it as a message though a TCP connection. The player on the other end of the TCP connection will then control the on-screen “player” via the same TCP connection.

I also have a need to supplement the TCP connection (as an option) with a custom publisher/subscriber network, in which my status messages are published, and control messages are subscribed to on another server. This protocol is a solved solution, but the publisher and subscriber should likely each run in their own thread, and access data inside the simpleUpdate() method. The user can choose between this protocol and standard TCP.

I’m having problems trying to figure out how it all goes together. First to tackle the multithreaded solved solution networking.

– Would the publisher and subscriber each need their own AppState (since each would be in its own thread)?

– What would that look like in simpleUpdate()? By this I mean, how could these two threads run at the same time as simpleUpdate() and access shared data in order to get commands and send status info?

I have looked at a similar question that had been posed, but that didn’t share data or run during simpleUpdate()

On a separate note, the TCP connection would be pretty standard. The first thing of note here is that the server isn’t headless. I want it to show on the screen what is going on, even if the player is being controlled remotely. Also, the remote user might not be running a java program to do the message handling. Since it would make the game socketed, any language could control it.

– Would SpiderMonkey be the tool to use for this, MirrorMonkey, or should I implement my own TCP server and message handling?

– What might this look like with the multithreading (since I can’t update anything in the networking loop)

So overall, I think I am looking at the following:

– A SimpleApplication that is the main game which allows the user to choose between remote protocols.

– If TCP is chosen, then I must run a single separate thread that is a server that sends status messages to a remote user, and reads commands form a user.

– If the solved-solution protocol is chosen, then I would need to spawn 2 communication threads, one for publishing status messages, and one for receiving control messages.

– Additionally, if the calculations involved with figuring out the info included in the status messages takes a long time, then this would also be in a (or possibly multiple) thread. In the (quite distant) future, there may be multiple players and as such each may need a thread for this.

Does what I’ve stated above look like a correct layout? Is there something that already does what I need that I just haven’t found yet? (I feel like I’ve already found it, but haven’t figured out how to use it.)

Also, sorry to kinda be this guy… and I’m also working in Eclipse… seriously. I kinda hate myself pretty bad for having to ask so much.

Respectfully, you do sound like you are in over your head a bit. I hardly know where to start.

If you want to control things from other languages then that pretty much rules out SpiderMonkey (and therefore MirrorMonkey as well). The SM protocols are not designed to work well with other APIs let alone other languages. SM is designed to send Java objects as small and fast as it possibly can. Consequently, both ends have to be setup in exactly the same way and if you adjust fields one end you have to adjust the fields on the other… there is no self-description built into the protocol because that would be extra and redundant information. However, it’s doing a lot for you that is really hard to get right.

If you handle your own network connections then on the server you will either want to have two threads per client or do like SM does with a single selector thread that offloads to the actual message processing thread (of which there could be more than one but that’s not implemented). Unless you really really really really know what you are doing with threads and selectors, I highly recommend avoiding that second route. It’s very difficult to get it right.

AppStates have nothing to do with threads. An AppState is a way of adding additional processing to an application’s update loop. If you attach an enabled AppState then it gets called once per update.

re: threading and access… with all of those threads you have running around, I don’t even begin to know what to tell you. Unless you are very experienced with multithreading then you will spend the rest of your life trying to sort all of this out, I think. Get very familiar with java.util.concurrent and read everything you can from Doug Leah. Personally, I’m not sure the level of concurrency you are suggesting will end up buying you anything. You are better off with less threads and not more in this case.

The JME scene graph can only be modified or safely queried on the render thread. There is a mechanism to enqueue your own Callables that can be used to invoke things on the render thread but you should carefully think about how your “domain objects” and the scene graph relate.

This is sort of a concern for SpiderMonkey users as well but on the client, SM is making sure all methods are delivered in sequence (so that app only has to worry about two threads, really)… and on the server it’s more likely that the data structures are designed for concurrent access anyway or the server is using some command queue pattern to simplify access to one thread (other than the command queue itself).

Thanks for the advice. I figured (feared) SpiderMonkey was Java-only.

You’re right about all those threads, it is way too much to deal with. I figured it would be a simple thing… Have 1 thread that ran the game itself, and 1 thread for the communication. That doesn’t seem to be the case at all.

I mentioned the AppStates because of the mention of Controls and AppStates on the jME multithreading page. I figured that’d be the way to go if it would logically keep my coding intact and easier to follow.

I am more interested in the physics than the screenGraph. The message I need to send are things like the results of “getCurrentLocation”, and I need to recieve message like “drive forward” or “turn left”. I was thinking of just using synchronized methods that update global variables within the SimpleApplication class. The status information (such as currentLocation) would be stored in synchronized setters each SimpleUpdate(), and the Communication thread would use a synchronized getter for the same data. Is this wrong?

I have done multi-threaded apps before, but nothing like this. Also, jME throws a wrench in the works by having that updateLoop and needing to have fluid graphics. I am all about simplifying if possible and am open to suggestions.

Finally, I will be looking into the work of Doug Leah. Thank you for the suggestion.

In reverse:

Doug Leah basically wrote the java.util.concurrent API but before that he was one of the leading guys to read on Java threading.

You will be better off treating your game objects as the “thing” and letting the scene graph update to them… either by having the game loop push updates to some queue that the update loop can see (like the Callable stuff built in) or by having data structures that can be shared safely across threads. If you find yourself having to “query the scene graph from some other thread” then you are doing it wrong.

AppStates and Controls are good for logically breaking up code that runs on the render thread.

Yeah, if you write your own networking layer then you will likely end up with at least 2 threads per client on the server. However, as much as possible these threads should do nothing but handle the networking. So a common architecture would be to stick the messages on some queue that a worker thread then handles for real. You want to avoid stalling the network channels if possible because then you start to push badness out in an ever-widening circle.