Handling connections client/server on spiderMOnkey

  1. I would to be able to listen for new client connections, so the server could broadcast a message to the old clients telling that now a new client has been added to the group. How can I put me between a new client connection on the server side?

    I mean in the console log I can read the output:
19-dic-2010 15.12.16 com.jme3.network.connection.TCPConnection accept
INFO: [Server#1][TCP] A client connected with address /127.0.0.1

I’ve read Server,Client,MessageListener,ServiceManager classes but still don’t know how to do that.
Is there an exception that I can handle? Is it the right way? Have you tryed different methods to handle client connections? Any other suggestions?

2) When I have only 1 client connected, if on the server side I'll use message.getClient().getClientID() it returns me 3 instead of 1.
Is it caused by the number of TCP/UDP connections?

Thank you in advance
c.

You can just add an ConnectionListener with addConnectionListener(ConnectionListener) to the Server and when a new Client connects the method clientConnected(Client) is called and when a client disconnects clientDisconnected(Client) is called.





And I think the 3 ID’s are for TCP, UDP and an combined one, but I’m not sure about that.



Hope I could help.

1 Like

Perfect, addConnectionListener does his work!

I thought the same for the ID. Anyone knows if 3 ID is the combined connection?

Thanks Creativ!

Does the server communicate only with broadcast messages or is it possibile to send messages to a certain client?

I mean, I’m trying to tell each connected client his own number seen from the server side, e.g.:

server: “new client connected. It is the 3th so I’ll tell him his the number 3 and not number 1 as he thinks to be.”

client: “I’ve received a message from the server where is written I am the number 3 client”.



I’ve store a ArrayList into the server which permits me to grow and shrink dinamically the number of connected clients.

Is it the right way to mirror the server view onto the clients?



Thanks in advance

c.

For now I’ve solved using this construct, but I think even if it works, it isn’t the right choise. Anyway, it is:

[java]

private static class myConnectionListener implements ConnectionListener{

public void clientConnected(Client client) {

try {

client.send(new MyMessageClass(“text”);

} catch (IOException ex) {

Logger.getLogger(ServerMain.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

[/java]

I think I shouldn’t use client directly, but maybe a native server method. Anyway it works. If you have for sure better ideas, please share them here.

c.

You can use the client in this way, no problem.



The problems start when you want to send a message to a client without first receiving either a connection event or a message from the client. While the server has a complete list of the connected Clients, it is not very intuitive to get a specific client.



I’ve added 2 methods myself, one to Client and one to Server to enable something like this:



Server.getClientByID(int clientId)



Where clientID is the id you get by doing Client.getID() in your connection listener. After this, all you need is a way to remember which clients are connected. But this is easy.



I already posted these two methods to Lars, but I’m thinking he is on holiday or something because I haven’t seen him around for a while.



Mark

I’ve implemented my system in the same way. The clients play without wait for server update. The server gathers all the status and send a collection of them to each client. Are the clients which have the duty to calculate their own position and the other client positions using the information written inside the GlobalStatusMessage sent from the server to them. So I think our implementation is about equal.

I’ve got the server which is a stand alone program which implements runnable interface and a client main which starts 2 thread: one for graphic [with simple update] and the other for connection.

The pseudo code is:

[java]

ServerClass {

@Override run () {

server.broadcast(globalStatus); // send to clients all the status

Thread.sleep(40); // ms

} — end run —

MessageListener() {

@Override messageReceived(message) {

updateGlobalStatus(); // collect all the informations

} — end messageReceived —

} — end messageReceived messageListener

} — end server class —



ClientConnectionClass {

@override messageReceived() {

updateClientStatus(); // update their vision of the world using the informations sent from the server

getCharacterPositionFromGraphicClass();



client.send(singleStatus); // send to the server only my singleStatus which contains my character position.

} — end messageReceived



} — end ClientConnection class —



ClientGraphicClass extends simpleUpdate {

characterposition;

@override simpleUpdate {

modifyPosition(); // is the code from walkingchar test

}

}

[/java]

In that manner each time the server broadcasts to all clients his collected view, all the clients do update their states and send back their own status. A sort of polling, if you are on the server side; a interrogation viewed from clients.

So the real question is that: is the correct way to keep the server polling the clients using sleep(40ms) and wait for the answers, or is better to force clients sending their status without interrogation?

r.



PS: Actually the server doesn’t wait for all the answers, because it wait onyl on base time, so if one client status doesn’t come in time between two “broadcast polling” the server will broadcast a globalStatus with old information, instead of wait to much time.

Nice job!

I’ve a question for you, as I see you are working with spiderMonkey: How do you manage the simpleUpdate method of clients?

I written 2 status classes:

One for singleStatus, which is the status of every single client. Each of them sends his own status to the server.

The other one is a worldStatus class, that is an arrayList of the previous singleStatus. One object of this class is created within the server for collect all togheter the different singleStatus and after that it will be send to all the clients. Each client in effect has one instance of worldStatus [and one singleStatus, as said before] so he can receive from server his “view of the world”.



Now the problem: When a client receives the worldsStatus he will update all the other singleStatus inside the wolrdStatus but not his own. After that he must send the to the server his own singleStatus.

But how can i send properly the position/rotation of the character? I have to use the walkdirection vector which is modified each loop by the simpleUpdate?



Thanks!

r.

I did it by just letting the client currently playing constantly send its position, and rotation information on a separate thread outside of the game loop. The current client doesn’t have to get permission from the server to move. (What I mean is the current client playing doesn’t send his information then wait for server to ok it or deny it and send back a new position in which the client then moves through). The current client moves as if it were a normal non multiplayer game but is just constantly sending his information. The advantages of doing it this way allows for you to give the user the idea of full control of their character. Response times are going to be better this way. Also you dont have to interpolate or extrapolate positions for the current client (only other connected players)The problem with this is cheating but that can be handled with a few checks client side and server side. Basically you would need to make sure the player isn’t moving faster than intended and if they are you have the server force them back to their previous valid position.

That kinda depends. Do you want to send one BIG object every so often, or do you want to send a SMALL object more often.



Cause what I’m currently doing is:



I have the client send the current status to the server. The server then does some checks and modifications on that status and sends it to all the OTHER clients. The server doesn’t send the status object to the original client. This saves bandwidth since the original client already knows the content of the status object anyways.



I send status objects to clients as they are received by the server. This means I’m sending more objects then when using your approach, but then again, the objects are a lot smaller. So I can’t really tell what the diffrence in performance would be. But my real time approach does mean (in theory at least) that the system would be less laggy.



Mark

I send status objects to clients as they are received by the server. This means I’m sending more objects then when using your approach, but then again, the objects are a lot smalle


I think it should be the same to send 1 big part every 3 seconds or 3 small parts each second. I thought to broadcast "one big message", so every istant every client has got exactly the same view of the world, a sort of shared view, because I was worried about syncronization. Maybe I should test it and see how it's lagging my system.
But for now, how did you have implement the gunshoots and the players deads? Raycasting or bullets are physics objects? Who decide if clientA [shot by clientB] is really dead? All on the client side? Which kind of controls on the server, or it is only a broadcast router?
I know it's a lot of question!

things like hits etc are determined serverside. Generally all things that can be cheated are done server side. So ammo count, hp that sort of thing. In the case of HP and ammo, both the server and the client calculate the current value. so anny additions and substractions should be sent to the server as well. When the server detects a definate state (out of ammy, dead) it sends this state back to the client.



The biggest win though, in my oppinion is not using the broadcast from spidermonkey, but setting up a braodcast of your own, exluding the originating client. This saves you 1 message per broadcast. which, in the case of many message can add up to a big improvement.

But with your method can’t you use broadcastExcept(client)? So you can deliver each status from clients to all the others except the only one who gave you that status?

To determine if a character is wounded did you use collision between physicsCaractherNode and bulletNode and the player who has been hit tells to the server that he is dead? Or did you cast a ray from the client who shoots and if the ray intersects a second player, the first one tells to the server that the latter is dead?

Ah, didn;'t notice that method before for some reason

Yes, that method would work.



One other approach is to make a hibryd form. Have the clients send status messages to the server as they come. Then have the server broadcast them as UDP messages. This si fast, but somewhat unreliable. Then, every second or so, have the server send a GlobalStatusMessage to sync all the clients, just in case some of the UDP messages have become lost. This is the best of both worlds really. It gives you fast updates and the ability to keep everything in sync. And you can have the large messages at a larger interval because you have the UPD messages brisging the gap in between.

ractoc said:
Ah, didn;'t notice that method before for some reason
Yes, that method would work.

One other approach is to make a hibryd form. Have the clients send status messages to the server as they come. Then have the server broadcast them as UDP messages. This si fast, but somewhat unreliable. Then, every second or so, have the server send a GlobalStatusMessage to sync all the clients, just in case some of the UDP messages have become lost. This is the best of both worlds really. It gives you fast updates and the ability to keep everything in sync. And you can have the large messages at a larger interval because you have the UPD messages brisging the gap in between.


I would just like to point out that it depends on your game but for an FPS broadcasting the information every second is going to be too much time between syncing frames and updates. 1 second = 1000 milliseconds and I'm sure you guys have played FPS games where you need a ping of less than 100 ms for it to even be playable. So syncing updates at 1 second intervals is essentially forcing every client to have 1000 ms by default.

If its not an fps game and doesn't require *precise* positions in that amount of time then 1 second should be fine. For simulators that may mimic an air force or naval ship fleet, those vehicles do not require constant updating of position, rotation or speed because in real life they do not have the unpredictability of a human and physics doesn't allow a million ton aircraft to turn on a dime like a human player can. I've seen simulations like this receive updates in 5 second intervals, or 5000 ms!!!

Repost:

To determine if a character is wounded did you use collision between physicsCaractherNode and bulletNode and the player who has been hit tells to the server that he is dead? Or did you cast a ray from the client who shoots and if the ray intersects a second player, the first one tells to the server that the latter is dead?

hhmmzz… I’m thinking the first option, collision detection would be the beest, since it would allow the posibility of sidestepping a bullet. Something the ray casting option does not allow. But it is a slightly more expensive option.