In my game I have a LocalGameServer, which is a multiplayer server for the game as a whole, and LocalLevelServers, which run the simulation for each level in play (its an action RPG so players might be on different levels). The problem I’m having is that, I can create the LocalGameServer, and it receives connections and messages fine, but the LocalLevelServer doesnt seem to receive messages. It does receive the connection, but not the message. The debug message I get says that the “Received message had no registered listeners”. Which is not true, I register all messages, including that specific one, for the LocalLevelServer. The particular message, a LevelServerConnectMessage, is not registered with the LocalGameServer. The message has the Serializable() property, extends AbstractMessage, and has a default parameterless constructor.
Any ideas? Can anyone think of a better way to do what I’m trying to do? I thought about farming out each level server to the player that is on the level server, but the problem is that if a player is behind a firewall or router, as most will be, he will not be able to receive incoming connections. So he would have to poll the game server for updates, which would forward all level server updates to him. Doesnt sound like a great idea.
Are you in fact running the servers on two separate ports or are you asking if you should?
You’d need to run each LocalLevelServer on its own port… Can I ask why this isn’t all done on a single process? Seems like a lot of work to me with regards to maintaining different processes
The LocalGameServer and LocalLeverServer run on separate ports, yes. At the moment there is only one LocalLevelServer. To be honest I havent entirely decided how to have each LocalLevelServer simulate collisions etc without causing problems with each other.
But this is where I’m stuck for now.
I dont spawn a new thread for each server, but they do have their own Server objects. The problem with using the same class I’ll be limited to a single level server per instance, which means players can only move levels once the host does. Not ideal for an action RPG.
EDIT: To perhaps make it a bit clearer, can anyone think of anything that I could be doing wrong that would cause the LocalLevelServer to not receive any messages even though it is on a different port? Or, can anyone think of a better solution that allows me to independently simulate more than one level at a time, on the same machine and potentially responding to more than one client. Theoretically I could have more than one level in the same space so long as each space was guaranteed not to intersect another. But the chances of a collision make me wary of that, it could cause nightmarish bugs.
Perhaps I’ll use a single server but send a Level ID or something back and forth. That way, when the message arrives at the network server, it knows which simulation engine or whatever to send it to. My LocalLevelServer then no longer listens for messages, it gets passed them by the LocalGameServer. Better solution?
Ah I thought you meant there were multiple JVM’s running with different processes ^^
You’d have to post a test case in order for anyone to be able to help you here
Store in the playerobject ON THE SERVER the levelid, then use that when determining which simulation to process the update.
This will probably be good enough for up to 100 players. if you plan with more you need a more intelligent concept.
As long as two Servers have different ports then there shouldn’t be an issue. But it is an odd use-case and I’ve never tested it personally. If they have the same UDP port and you are sending unreliable messages then it might be random which Server instance picks up those messages. Though if you try to launch two servers for the same port then the second will fail… so I’m not sure what’s up.
Regarding the other posts, it is unusual to run more than one Server for this purpose. It doesn’t really buy you anything with respect to performance and complicates things a bit.
A HostedConnection has session attributes that you can set for each connected client. You could put the ID for the level or even the level object in a setAttribute() and then look it up with each message to figure out where to route them.
I’m not specifying whether to use UDP or TCP, but I think I noticed TCP being mentioned. When I accidentally used the same port, it couldnt start the server - couldnt listen on that port. So that doesnt work anyway, as you say pspeed.
I might upload a sample later, but I’ll probably just go with a single sever and use setAttribute() to figure out where each player is (and thus which simulation to forward their messages to).
The reason I wanted the different servers was simplicity, so that I would not have to do any message routing myself.
Only planning on 8-12 players max. My only concern is that each level will have monsters in it. What I plan to do though is use a different synchronization strategy for monsters. Provided any random number generator used in the AI scripts is started with the same seed, the results should be deterministic. So hopefully I wont have to sync as often as I do for players. I also plan to use interpolation only for players, not for monsters. I’ll just synchronize their state with the server now and then.
Just a little update if anyone is interested.
It was me all along. Everything was working fine - the problem was that I am running both the server and the client on the same machine. It looks like the server listener and client listener both picked up the message. It was delivered to the server (as it should be) and not to the client.
So it was working fine all along, it was the debug exception that threw me off and made me think it was not working. I didnt think the debug message could have been generated by the client side registry! My bad, sorry everyone.
EDIT: Yes, since running everything locally means it is technically a listen server, I’m going to pass the messages directly instead of going via the network stack. That will bypass these issues. Should have done that in the first place!