Kryonet - Server & multiple listeners (trying to make a queue and GameRooms)

Hello!

I’m trying to code a server like this:

The main class is the queue.
Queue has one slot where user awaits for his opponent.
When queue reaches two players, new ‘GameRoom’ object is created and both of them are passed to it’s constructor (we don’t need them in queue anymore)
In this ‘GameRoom’ we make a gameloop that handles their 1v1 match.
In the same time, queue is empty and awaits for the same situation - for two players etc…

First of all, I’m a newbie with networking, but I figured out that I can’t open a listener ‘behind’ the main listener (in a GameRoom) cause it would be unreachable.

server.addListener(new Listener() {
			public void received (Connection c, Object object) {
			
				
					//c.setIdleThreshold(1);
				
					if(numberOfPlayers == 2){
						System.out.println("NEW GAME ROOM CREATED");
						GameRoom gameRoom;
						
						gameRoom = new GameRoom(player_list.get(0), player_list.get(1), gameID++);
						numberOfPlayers = numberOfPlayers - 2;
					}
					
				
					if (object instanceof Login) {
						System.out.println("LOGIN FROM: " + c.getRemoteAddressTCP());
					}
					
			    }
			}
			private boolean isValid (String value) {
				if (value == null) return false;
				value = value.trim();
				if (value.length() == 0) return false;
				return true;
			}
			public void disconnected (Connection c) {
				numberOfPlayers--;
				}
			

			
		});
		server.bind(Network.port, 8889);
		server.start();
			
		
	}

This is the listener code - it’s just ‘taken’ from Kryonet.

My question is: How should I handle this kind of game?
Can I somehow separate listeners/connections to queue and gamerooms?

I thought of something like this:
User connects and gets his ‘GameRoom Unique Number’. When a packet with for ex. position comes to the server it reads to which GameRoom this user belongs and passes this position to him, but I think this method is not efficient, cause let’s see if we have 10 000 players. There are 10 000 iterations over the players list (with only single packet).

I hope that you understood what I’m trying to accomplish. If there is anyone that could help me with this idea - just point me - how should I code it - I would be grateful!

[quote]First of all, I’m a newbie with networking, but I figured out that I can’t open a listener ‘behind’ the main listener (in a GameRoom) cause it would be unreachable.
[…]
I thought of something like this:
User connects and gets his ‘GameRoom Unique Number’. When a packet with for ex. position comes to the server it reads to which GameRoom this user belongs and passes this position to him, but I think this method is not efficient, cause let’s see if we have 10 000 players. There are 10 000 iterations over the players list (with only single packet).
[/quote]
You can pass the connection-objects of your 2 players to the gameroom and add a new gameroom-listener to these two connections to listen for position updates within the gameroom. You also don’t need to call the sendUDP/TCP methods from the server instance, just call them from the individual connection-instances. You can also remove the first listener (the one from queue i think) from these connections after passing them to the gamerooms.

Thank you for your reply!

This is exactly how I did:

In queue:

public Main () throws IOException {
		server = new Server(9000000,9000000) {
			protected Connection newConnection () {
				Character player = new Character();
				player_list.add(player);
				numberOfPlayers++;
				return player;
			}
		};
gameRoom = new GameRoom(player_list.get(0), player_list.get(1), gameID++);

In GameRoom:

Character player_left, player_right;
	public GameRoom(Character p_left, Character p_right, int GameID) { // will probably remove server
	
		player_left = p_left;
		player_right = p_right;
		
		player_left.x = 100;
		player_left.y = 500;
		
		player_right.x = 1000;
		player_right.y = 500;
		
		player_left.addListener(new Listener() {
			public void received (Connection c, Object object) {
				
				if (object instanceof PlayerPosition) {
					PlayerPosition pp = ((PlayerPosition)object);
			
					player_right.sendTCP(pp);
					
				}
			}

			private boolean isValid (String value) {
				if (value == null) return false;
				value = value.trim();
				if (value.length() == 0) return false;
				return true;
			}
			
			public void disconnected (Connection c) {
				
				}
		});
		
		
		player_right.addListener(new Listener() {
			public void received (Connection c, Object object) {
				
				if (object instanceof PlayerPosition) {
					PlayerPosition pp = ((PlayerPosition)object);
					player_left.sendTCP(pp);
				}
			}

			private boolean isValid (String value) {
				if (value == null) return false;
				value = value.trim();
				if (value.length() == 0) return false;
				return true;
			}
			
			public void disconnected (Connection c) {
				
				}
		});
	}

Character class extends Connection. I can use all of the methods from Conn on player_left & player_right, but I don’t know if I should add these listeners here in GameRoom to each connection, or not O.o

It is supremely important that you set the object/writeQueue buffer size correctly and as small as possible or your server will drown in garbage-collection because of all the buffers that get allocated (one object-buffer per sendTCP/UDP call!) I had this in one project, it was devastating for the server-performance.

server = new Server(1024*10/*QUEUE-BUF*/, 150/*OBJ-BUF*/) {

1300 bytes of payload should be your max packet size, your object buffer shouldn’t be bigger: https://en.wikipedia.org/wiki/Maximum_transmission_unit
A 2D float vector will be approximately <2 byte objectid + 2*4 bytes float fields =~ 10 bytes! You do not need such large object buffer sizes.

Also shouldn’t this

gameRoom = new GameRoom(player_list.get(0), player_list.get(1), gameID++);

be like this:

gameRoom = new GameRoom(player_list.get(remove(0)), player_list.get(remove(0)), gameID++);

You could add some code to close the GameRoom as soon as one player quits. Everything else looks ok to me.

Thank you!