对 IRC 机器人的调用速率限制

Rate-limit calls to an IRC bot

我正在开发一个 IRC 机器人,它有命令 !Scouter,它会生成一个随机数....我已经完成了,我想做的是一个冷却系统,以防止人们发送垃圾邮件一遍又一遍。

这是我的代码。

public class Twitchbot extends PircBot {
    Random dice = new Random();
    int number;

    for(int counter=1; counter<=1;counter++) {
        number = 1+dice.nextInt(9001);
        System.out.println(number + " ");
    }

    public Twitchbot() {
        this.setName("Blah");
    }

    public void onMessage(String channel, String sender, String login, String hostname, String message) {
       if (message.equalsIgnoreCase("!Scouter")) {
           sendMessage(channel,": The time is now " + sender + number);
           for(int counter=1; counter<=1;counter++) {
              number = 1+dice.nextInt(9001);
              System.out.println(number + " ");
              try {
                 Thread.sleep(5000);
              } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
              }
           }
       }
    }
}

我尝试使用此代码来冷静一下

 try {
    Thread.sleep(5000);
 } catch(InterruptedException ex) {
     Thread.currentThread().interrupt();
 }

但它所做的只是在睡眠 5 秒后执行代码。我不希望命令 !Scouter 在冷却期间注册。有更好的方法吗?

问题是 onMessage 是异步调用的,所以你不能阻止它被休眠调用。

最简单的解决方法是将当前时间存储为实例变量,如果存储时间与当前时间之间的差异小于 5 秒,则 return 立即在 onMessage 中。

您可以使用以下方法在成功调用时保存当前系统时间:

lastCall = System.currentTimeMillis();

之前,你检查

if(System.currentTimeMillis() - lastCall >= DELAY)

其中 DELAY 是以毫秒为单位的时间(1 秒等于 1000 毫秒)。

如果该语句为真,则将 lastCall 设置为当前时间:

lastCall = System.currentTimeMillis();

并调用正常代码。


看起来像这样:

long lastCall = 0L; //Initializing 

public void onMessage(String channel, String sender,
        String login, String hostname, String message) {

   if (message.equalsIgnoreCase("!Scouter")) {
       if(System.currentTimeMillis() - lastCall >= 5000)
       {
           lastCall = System.currentTimeMillis(); // Set lastCall again
           sendMessage(channel,": The time is now " + sender + number);
           for(int counter=1; counter<=1;counter++) {
             number = 1+dice.nextInt(9001);
             System.out.println(number + " ");
           }
       }
   }
}

我不完全了解你的系统的功能,但我看到你的系统每次进入睡眠时都会卡住。

如果您想摆脱这种行为,一个好的方法是使用线程作为匿名 class 调用,并在后台执行操作。

我会这样做:

if (message.equalsIgnoreCase("!Scouter")) {
            sendMessage(channel,": The time is now " + sender + number);
            new Thread() {
                @Override
                public void run() {
                    for(int counter=1; counter<=1;counter++) {
                        number = 1+dice.nextInt(9001);
                        System.out.println(number + " ");
                        try {
                            sleep(5000);
                        } catch(InterruptedException ex) {
                            Thread.currentThread().interrupt();
                        }
                    }
                }
            }.run();
        }

希望对您有所帮助。