javatimeircrate-limiting

Avoiding rate-limiting (throttling) in java (IRC)


So I've been writing a java-based irc-bot, which is fairly simple. Makes a socket connection to a server, attaches buffered readers / writers to the socket, and then reads / writes using those buffers.

I've not run into issues except for when I was printing out a json object and got kicked off the network for excessive flood. I'm not sure of the message rate limit for the network, but I do pass all my messages through the same simple function.

I'm hoping to add some kind of x bytes / timeframe limit to it. Someone suggested that I look into NIO, but that seems to be over-engineering the issue a little bit.

Here's what my current write-to-irc channel method looks like:

public static void writeMsg(BufferedWriter writer, String Channel, String Message) {
    try {
        System.out.println("Bot Command: PRIVMSG " + Channel + Message); //diagnostic
        writer.write("PRIVMSG " + Channel + Message);
        writer.flush();
    } catch(IOException ioe) {
        ioe.printStackTrace();
    }
}

Example of what might be passed into / out of that function:

Input:

writer (my BufferedWriter object), "#Testing1234: ", "!wiki China";

Output:

PRIVMSG #BeginnersProgramming :http://en.wikipedia.org/wiki/China


Solution

  • I'm hoping to add some kind of x bytes / timeframe limit to it

    The easiest way to do that would be along the lines of

    final int rateLimit = 50; // Bytes per second
    
    final float msPerByte = 1000.0f / rateLimit;
    
    writer.write(message);
    
    int numBytes = message.length();
    
    Thread.sleep((int)(msPerByte * numBytes + 1));
    

    However, depending on the length of the message, the single burst of one message may be already triggering the rate limit of the server. In this case you'd have to split the message into smaller parts and send one after another with the appropriate delay between.

    If the rate limit is enforced only on a messages-per-timeframe basis, all you need to do is sleep() a constant time after each message.

    I believe though that there are more complex algorithms at work, which may include more time-based parameters to decide.