Yup, not bothering with NIO at this point.
Also, even though I haven’t coded much networking stuff before, I have a pretty good understanding of how it works, at least.
I got the chat client working via multi-threading. The server has a thread to listen for new connections, a thread for each connected client, and a thread to kill client connections that haven’t sent anything in a certain time interval (currently a minute). I’ve got a lot of methods in here that appropriately synchronized, and have had no concurrency issues so far (with my limited testing). It’s quite wasteful in the number of threads I have, but in 99% of my personal cases this will be no big deal.
The client has one thread that listens for data, and one thread that constantly sends out heartbeat data (basically an empty object gets sent to the server every interval, currently 10 seconds). I’m aware that the latter thread could easily be coded into the game loop, but I decided I just wanted to keep things simple and clean - I shouldn’t need to bother with heartbeats or anything in any games or programs that implement this “framework.”
I’ve also implemented separate hooks for the following situations:
- A client disconnects manually
- A client times out and so is disconnected
- The server shuts down on purpose
- The server shuts down unexpectedly
- A new client has connected
- The server checks that everything is legal before it sends it back to clients
As far as I’ve been able to tell given my limited testing, all the functionality works when the framework is implemented into the chat client.
I then started do a very very simple networked game - basically each player controls one Entity (which is just a drawn oval), their keyboard input is sent to the server, and the server then sends back any entities that have been updated. I almost had this done then realized that I was implementing it stupidly (I was allowing the client to do a lot of stuff which would allow hackers to run rampant) so I scrapped it and started again.
Once I’ve got that solid, I’ll slowly add a few features to it and make it some sort of very simple game. Then I’ll post that up here and we can try to break it.
From there, I’ll start implementing it into actual projects. Overall I’m not worried, because although I haven’t spent much time doing networking myself I’m frequently exposed to clean, working, code.
The one complication with my game implementation (input is sent to the server, the server sends back new positions) is that in very laggy circumstances this will get very annoying. I’ve played games that do it this way and it is very very far from acceptable. I’ve been cooking up hybrid approaches, like allowing movement to be pretty much free reign to a certain point (client controls movement and sends updates to server unless the delta is too large) but all important actions like attacking and such must be verified by the server first. But then, of course, depending on the type of game it is, there can end up being large deltas between what the client sees and what the server sees.
So, in summary, I’m only worried about figuring out how to deal with latency at this point - the actual implementation is simple enough for now that I’m fine.