Hello!
A few days ago I
wrote about my problem with Java NIO delays while sending packets. So, as I was advised, I'm opening a separate thread for this issue. I made a minimal working example, where the problem is reproduced.
Here I'll show only parts of the code, full version is available
here.
So, the program has two entities: Server and Client. If you start an application in a server mode, then a Server is created, starts to listen for new connections, and a new Client is automatically created and tries to connect to the Server. In client mode only a Client is created and connects to the Server.
The application also creates a new basic GUI window and starts an event loop, where everything happens.
The Client sends packets to the Server. It handles them by just logging the fact of accepting. There are two types of packets the Client can send: periodical packet (with an incremental ID) and an event packet (application reacts to pressing SPACE or M buttons).
Client sends packets:
public void update
(Time dt
) throws IOException { if (!isConnected
) return; if (tickClock.
getElapsedTime().
compareTo(Time.
getSeconds(1.
f / 20.
f)) > 0) { Packet intervalUpdatePacket
= new Packet
(); intervalUpdatePacket.
append(PacketType.
INTERVAL_UPDATE); intervalUpdatePacket.
append(intervalCounter
++); PacketReaderWriter.
send(socketChannel, intervalUpdatePacket
); tickClock.
restart(); } } public void handleEvent
(Event event
) throws IOException { if (isConnected
&& (event.
type == Event.
Type.
KEY_PRESSED)) { KeyEvent keyEvent
= event.
asKeyEvent(); if (keyEvent.
key == Keyboard.
Key.
SPACE) { LOGGER.
info("press SPACE"); Packet spacePacket
= new Packet
(); spacePacket.
append(PacketType.
SPACE_BUTTON); PacketReaderWriter.
send(socketChannel, spacePacket
); } if (keyEvent.
key == Keyboard.
Key.
M) { LOGGER.
info("press M"); Packet mPacket
= new Packet
(); mPacket.
append(PacketType.
M_BUTTON); PacketReaderWriter.
send(socketChannel, mPacket
); } } } Server accepts packets:
private void handleIncomingPackets
() throws IOException { readSelector.
selectNow(); Set
<SelectionKey
> readKeys
= readSelector.
selectedKeys(); Iterator
<SelectionKey
> it
= readKeys.
iterator(); while (it.
hasNext()) { SelectionKey key
= it.
next(); it.
remove(); SocketChannel channel
= (SocketChannel
) key.
channel(); Packet packet
= null; try { packet
= PacketReaderWriter.
receive(channel
); } catch (NothingToReadException e
) { e.
printStackTrace(); } if (packet
!= null) { // Interpret packet and react to it handleIncomingPacket
(packet, channel
); } } } private void handleIncomingPacket
(Packet packet, SocketChannel channel
) { PacketType packetType
= (PacketType
) packet.
get(); switch (packetType
) { case INTERVAL_UPDATE
: int intervalId
= (int) packet.
get(); //LOGGER.info("handling interval packet: " + intervalId); break; case SPACE_BUTTON
: LOGGER.
info("handling SPACE button"); break; case M_BUTTON
: LOGGER.
info("handling M button"); break; } } And here is the problem: I have quite big delays between pressing a button (and sending a corresponding packet from the Client) and accepting this packet on the Server. If I start a new instance of the application in a client mode (just add a new Client in short), the delays become even bigger.
I don't see any reason why these periodical packets create so much network load that other packets just cannot get through, but maybe I'm just missing something. Here I have to say that I'm not a Java expert, so don't blame me too much for not seeing something obvious
Does anyone have any ideas?