javasocketsirc

Java socket output has delayed first message


I'm having a very strange problem with sockets in Java. It could be caused because of my lack of knowledge about sockets but here it is:

I'm using a socket to connect to an IRC-server. The connection is made perfectly and I receive all the messages the IRC-server is sending me. When the connection is made, I authenticate to the server and I start a seperate thread to receive what the server sends me. In that thread I send a message once when connected to make the program join a certain channel.

boolean joined = false;
        while ((line = getInput().readLine()) != null) {
            if (!joined) {
                getOutput().println("JOIN #Random");
                getOutput().println("JOIN #Modnar");

                if (line.contains("JOIN :#Random")) {
                    joined = true;
                    System.out.println("JOINED #Random= true");
                }
            }

At the end of this method I call getOutput().flush();

Now when I'm trying to send a message TO the IRCserver via the client I'm writing, it seems to take ages before the first message gets through. When it finally get's through everything seems to be working fine. All following messages are handled immediately. It's just that first message I'm sending after being connected and having joined that channel that takes long.

The method I'm using to send a message to the server is very simple:

public void sendToServer(String input) {
        getOutput().println(input);
        getOutput().flush();
    }

Is there anyone who has a clue why the first message is taking so long to transmit to the server while all the following (after the first finally arrived) go well?

If it might be worth mentioning: I'm using a Tomcat6 for my servlets on which I make the connection and an UnrealIRCd as IRC-server. The messages are send to the servlet via AJAX. (But the sending to the server seems to go well, since the System.out I'm doing when a message is send is printed immediately in my Tomcat-log, so the delay is in the socket OR in the IRC-server..)

If more info is needed, I shall try to provide it, since this might look quite complicated like this..


Solution

  • Your code appears to send the JOIN commands every time it goes around the while loop, which appears to be once for every line the server sends you, until you finally get the response from the server confirming that you've joined the channel.

    This means you'll end up sending those JOIN commands a very large number of times. IRCDs are designed to only handle a set rate of commands per second from each client - so this is probably what's lagging you (your later commands end up on the end of a very long queue filled with lots of JOIN commands).

    Instead, you should only send the JOIN commands once only, by setting the flag as soon as you send them:

    boolean sent_join = false;
    boolean joined = false;
    
    while ((line = getInput().readLine()) != null) {
        if (!sent_join) {
            getOutput().println("JOIN #PrinZ");
            getOutput().println("JOIN #Trinorae");
            sent_join = true;
        }
    
        if (line.contains("JOIN :#prinz")) {
            System.out.println("JOINED #prinz = true");
            joined = true;
        }
    }
    

    Note that you can't send your JOIN commands until after you're registered, which is indicated by an 001 numeric, so you may need to wait for that line before sending them.

    Note that line.contains is not a very robust way of parsing IRC messages. If I send you a message that contained "JOIN :#prinz", it'd trigger on that too. You should be breaking each incoming message up into source, command, destination and arguments.