socket.io-client-java
socket.io-client-java copied to clipboard
socket.emit() from the client slows down all threads for 2 milliseconds
I'm using this library with LibGDX and I have all of my socket related activity in a different thread from the LibGDX graphics thread. It runs perfectly fine for all received requests but every time I try to emit a new request from the client, every single thread I have (including the graphics thread) freezes for 2 milliseconds (I calculated). To reiterate, this is when I call "socket.emit(id, data);" from the client. For good measure I've got the code of Client.java below which contains everything I have that deals with this socket library. The issue occurs on line 133 with "socket.emit("move", data);"
EDIT: After Testing around more with this. If the client receives a request very often, the same effect of every thread slowing down occurs.
public class Client implements Runnable {
private GameState gs;
private Socket socket;
private static float UPDATE_TIME = 1/60f;
private static float timer = 0;
private String server = "http://localhost:8080/";
public Client(GameState gs) {
this.gs = gs;
}
@Override
public void run() {
try {
socket = IO.socket(server);
} catch (URISyntaxException e) {
e.printStackTrace();
}
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
@Override
public void call(Object... args) {
Gdx.app.log("SocketIO", "Connected");
gs.connectionState = GameState.ConnectionState.DOWNLOADING;
}
}).on("init", new Emitter.Listener() {
@Override
public void call(Object... args) {
gs.mapDataString = (String) args[0];
gs.me = gs.newPlayer(true);
gs.me.x = loadNumberType(args[1]);
gs.me.y = loadNumberType(args[2]);
gs.me.id = (String) args[3];
try {
JSONArray players = (JSONArray) args[4];
for(int i = 0; i < players.length(); i++) {
JSONObject playerObject = players.getJSONObject(i);
String id = playerObject.getString("id");
float x = (float) playerObject.getDouble("x");
float y = (float) playerObject.getDouble("y");
int rotation = playerObject.getInt("rotation");
GameState.Player player = gs.newPlayer(false, id, x, y, 0, 0, rotation);
gs.getIndexedPlayers().put(id, player);
if(!gs.getConnectedPlayerIDS().contains(id))
gs.getConnectedPlayerIDS().add(id);
}
} catch (JSONException e) {
e.printStackTrace();
}
gs.connectionState = GameState.ConnectionState.READING;
}
}).on("newplayer", new Emitter.Listener() {
@Override
public void call(Object... args) {
String id = (String) args[2];
if(!id.equals(gs.me.id)) {
float x = loadNumberType(args[0]);
float y = loadNumberType(args[1]);
GameState.Player newPlayer = gs.newPlayer(false, (String) args[2], x, y, 0, 0, 0);
gs.getIndexedPlayers().put(id, newPlayer);
if (!gs.getConnectedPlayerIDS().contains(id))
gs.getConnectedPlayerIDS().add(id);
}
}
}).on("delplayer", new Emitter.Listener() {
@Override
public void call(Object... args) {
String id = (String) args[0];
if(gs.getConnectedPlayerIDS().contains(id))
gs.getConnectedPlayerIDS().remove(id);
if(gs.getIndexedPlayers().containsKey(id))
gs.getIndexedPlayers().remove(id);
}
}).on("updateplayer", new Emitter.Listener() {
@Override
public void call(Object... args) {
try {
JSONObject updateInfo = (JSONObject) args[0];
String id = updateInfo.getString("id");
if(!id.equals(gs.me.id)) {
float x = (float) updateInfo.getDouble("x");
float y = (float) updateInfo.getDouble("y");
int rotation = (int) updateInfo.getInt("rotation");
if (gs.getIndexedPlayers().containsKey(id)) {
GameState.Player p = gs.getIndexedPlayers().get(id);
p.x = x;
p.y = y;
p.rotation = rotation;
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}).on("getposition", new Emitter.Listener() {
@Override
public void call(Object... args) {
float oldX = loadNumberType(args[0]);
float oldY = loadNumberType(args[1]);
int oldRotation = Integer.parseInt(args[2].toString());
GameState.Player me = gs.me;
if(me != null && (me.x != oldX || me.y != oldY || me.rotation != oldRotation)) {
JSONObject data = new JSONObject();
try {
data.put("id", me.id);
data.put("x", me.x);
data.put("y", me.y);
data.put("rotation", me.rotation);
data.put("xVector", me.xVector);
data.put("yVector", me.yVector);
socket.emit("move", data);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
socket.connect();
}
private float loadNumberType(Object o) {
return Float.parseFloat(o.toString());
}
public void dispose() {
}
} `
Bro i have the same problem.. U solved it??????
@Xakinlee @Deery50 , guys, did you solve the problem? I also have the same issue. By measuring socket.emit processing time (I did 3 tests) found that:
- If I try to make test loop for example for loop < 1000 just to do stress test Result is ===> elapsedTime: 1500 ns (about) (test foor loop is placed in public void create() )
- If I try to make just to spam socket.emit in every render iteration (60 times a second ) Result is ====> elapsedTime: 273300 ns (about)
- If I put the test loop from the previous test into public void render() Result is ===>
render elapsedTime: 245100 ns (Look at this, this is a first iteration in for loop in one render cycle, very weird) elapsedTime: 5600 ns (this is the second iteration in for loop in the same render cycle) elapsedTime: 600 ns elapsedTime: 700 ns elapsedTime: 300 ns elapsedTime: 400 ns elapsedTime: 300 ns
processing time in third, fourth, n-th iteration in the for loop look much better than first/second for some reason. This is weird situation that I found, and have no answer for this behaviour. Also it will be good if you guys have somne answers or some advices. Best regards!
Same issue :(