SFML community forums

Bindings - other languages => Java => Topic started by: kalimatas on November 06, 2014, 02:53:54 pm

Title: Delays while sending packets with NIO
Post by: kalimatas on November 06, 2014, 02:53:54 pm
Hello!

A few days ago I wrote (http://en.sfml-dev.org/forums/index.php?topic=16678.0) 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 (https://github.com/kalimatas/jsfml-game-server).

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?
Title: Re: Delays while sending packets with NIO
Post by: eXpl0it3r on November 06, 2014, 03:03:17 pm
I suggest to ask the question in a Java related community, because on the SFML forum, you won't really find active and experienced Java developers and at other places, you'd get many. :D
Title: Re: Delays while sending packets with NIO
Post by: kalimatas on November 06, 2014, 03:05:47 pm
I duplicated the question on StackOverflow, but also posted it here in hope anyone had the same issue  :)