[KryoNet] Client can't send and receive at the same time ?

Hi,

I’m trying to code a simple client/server using KryoNet but I’m struggling with something, my client can’t receive packets while sending.

When I hold the right key I want my player to move 1pixel to the right. In my situation when I hold the right key my player moves 1 pixel to the right, then stop moving, and finally when I release the key he literally teleports himself in the right direction. I other words the client receive almost all the packets at one time.

Here’s my code:

Client:


public void launch() throws SlickException, IOException {
		AppGameContainer container = new AppGameContainer(this);
		container.setMinimumLogicUpdateInterval(10);
		container.setMaximumLogicUpdateInterval(10);
		container.setUpdateOnlyWhenVisible(false);
		container.setAlwaysRender(true);


		client = new Client();
		ClassRegister.register(client.getKryo());
		client.addListener(new CustomListener(this));

		client.start();

		if (!connected) {
			Log.set(Log.LEVEL_TRACE);
			try {
				client.connect(5000, host, port);
				connected = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		container.start();
	}

CustomListener:

@Override
	public void received (Connection connection, Object object) {
		
		if (object instanceof MoveResponse) {
			MoveResponse response = (MoveResponse) object;
			getPlayer().move(response.dir);
		}
	}

Server:

private void start() throws IOException {
		server = new Server();
		ClassRegister.register(server.getKryo());
		server.bind(port);
		server.addListener(new ServerListener(this));
		server.start();
		Log.set(Log.LEVEL_TRACE);
	}

ServerListener:

@Override
	public void received(Connection connection, Object object) {
                if (object instanceof MoveRequest) {
			MoveRequest request = (MoveRequest) object;
			
			MoveResponse response = new MoveResponse();
			response.dir = request.dir;
			connection.sendTCP(response);
		}
	}

Input:



public void update() {
		movePlayer();
	}

private void movePlayer() {
		if (pressedRight) {
			sendMoveRequest(3);
		} else if (pressedUp) {
			sendMoveRequest(1);
		} else if (pressedDown) {
			sendMoveRequest(2);
		} else if (pressedLeft) {
			sendMoveRequest(4);
		}
	}

	public void keyPressed(int key, char c) {
		if(key == goDown) {
			pressedDown = true;
		} else if(key == goLeft) {
			pressedLeft = true;
		} else if(key == goUp) {
			pressedUp = true;
		} else if(key == goRight) {
			pressedRight = true;
		}
	}

	public void keyReleased(int key, char c) {
		if(key == goDown) {
			pressedDown = false;
		} else if(key == goLeft) {
			pressedLeft = false;
		} else if(key == goUp) {
			pressedUp = false;
		} else if(key == goRight) {
			pressedRight = false;
		}
	}

I seriously don’t see where I’m messing up :frowning: Any help?

You can send from any thread. Your send will either happen immediately (which is very likely) or it will be queued and later sent on the network thread. You always receive on the network thread. If you manipulate your game state from the network thread, you can have synchronization problems with your game thread. Also, while you block the network thread, you won’t be able to receive more objects and won’t be able to send data if the your send had to be queued. You can use Listener.QueuedListener to add runnables to a list, then in your game thread you can run these. Be sure to use proper synchronization for this list though (eg, in a synchronize block on the list, copy the contents to a second list, clear the list, then run the runnables in the second list outside of the synchronize block).