For a school project, we're supposed to create a multiplayer game in Java (it should be client/server) which can be played over the internet (we're programming this at school, so it's not homework). The game is turn-based, but there should be a chat, which ofcourse is real-time. However, none of us has experience with network programming and the more I read about it, the more questions I seem to have.
My first thought was to use the socket API to implement the multiplayer part. The server waits for new data from the clients. However, there are multiple kinds of data to receive, like chat messages, movement, etc. Also, once the connection to the server is made, some initial data (like the Player's name) should be sent. The server should be able to see what kind of message it received, but how? I was thinking of creating a class Message
with a string field type
. But in my server code, I will get code like this:
if (message.type.equals("message")) {
// code to execute for chat messages
} else if (message.ty开发者_运维知识库pe.equals("movement")) {
// code to execute for movement
} else if () {
// ...
} else {
// ...
} // Please ignore syntax errors :P
When there are a lot of different kinds of data to send (and there WILL be), this doesn't look like the most efficient way. Also, this would mean both the server and client should have this Message-class/interface (duplicate code).
What about other game stuff? For example, player 1 moves his character to a position which defeats another character. The client of player 1 calculates this defeatment and applies the correct actions. But what should be send to the server? Just the new player position or also the defeatment? With the first option, it means all other clients should do the calculations. Couldn't this cause any trouble? As I have no prior network programming experience, I'm a bit confused on how to do all these things.
I've also read in another thread here on Stackoverflow that RMI might be a better option. Having read some information about this, I understand what RMI is, but I'm still not able to see whether it is a good option for this project or not. Any tips for this?
As you see, I'm a bit confused on how to start with the networking part of this project. I've searched for some game programming books (for Java ofcourse), but none of them are focussed on the networking part. I've also searched for Java networking books, but these seem to be focussed on the technology, not on good code practices.
If anyone knows a good book or has some advice in the right diection, it would be greatly appreciated.
Thanks
You're on the right path, but there are few things to clear up.
If you're using sockets, you've figured out that you need to define a protocol - a mutual language for communicating moves and the state of the game. Sockets will let you send any sort of data in pretty much any format you want. It looks like you're thinking about serializing a class Message to send this type, this is one of doing things. If you use RMI (which has its own protocol), you will act as if you were calling Java methods, but in essence you're doing something similar, serializing data and passing it over a socket.
There's nothing implicitly wrong about sharing code between the client and the server - in fact, most services do this in some form. Your client and server could both use a common library to define the message classes being passed around. RMI uses method stubs to determine the interface. Web services of all sorts define how methods are invoked. The general idea is to only expose the interface, not the implementation.
Regarding your code, it might be cleaner to have a different Message subclass for each message type and you could put additional parameters for each message. You could then have a MessageProcessor class like:
class MessageProcessor{
void process(Move1Message m) {...}
void process(Move2Message m) {...}
....
}
Regarding what to send - the general principle should be that the client is responsible for sending their move to the server, anything else it does is a bonus, because the server needs to verify the legality of the move. The server should always be the determiner of the state of the game to avoid cheating and erroneous client implementations
Unless you're interested in learning how to implement your own protocol or use the Java sockets library, it's going to be easier to use RMI. You could also use SOAP, REST or any other protocol, but I wouldn't bother thinking too hard about which one to use at the moment. I don't have any suggestions beyond the RMI documentation, though I think this book had lots of code examples for networking.
when going with sockets each client will have it's own connection on which a server thread will wait (don't forget to flush the stream on client side or you'll wait forever)
each line will be a separate message and to differentiate the message types you can use a "header" at the start of each message (a specific 3-character sequence at the start) say msg
, mov
, lgn
and use a trie-like selection with switches to quickly decide which one you got
when using RMI you can have the server keep a manager object (exported and registered in the registry) on which a client can request a "connection"-object which will be the same as the connection in the socket implementation but you'll be able to have a method for each thing you wanna do though the callbacks will need to be done in some other way (with sockets you have a connection ready for it)
精彩评论