IMAP 空闲,是否有可能错过事件?

IMAP Idle, possibility to miss events?

我在 java 中实现了一个邮件侦听器,侦听器进入 IDLE 直到新邮件到达,它打印电子邮件主题并立即再次返回 IDLE。

我是否有可能错过我发出的两个 IDLE 之间的事件(新电子邮件)?

例如,我试过在再次进入 IDLE 之前休眠 10 秒,在这 10 秒内我向我正在监控的收件箱发送了 2 封电子邮件,在 10 秒之后我又回到了 IDLE我的 MessageCountListener 只接到过一次电话,是第一封电子邮件。第二个错过了。

也许我不应该依赖MessageCountListener

       messageCountListener = new MessageCountListener() {
            //lets go into idle again and then handle the message
            public void messagesAdded(MessageCountEvent ev) {
                Message message = ev.getMessages()[0];
                try {
                    SimpleLogger.info("New message, subject: " + message.getSubject());
                } catch (MessagingException e) {
                    e.printStackTrace();
                }

                //GeneralUtility.threadSleep(8000);

                startImapIdle();
            }

startImapIdle() 最初被调用,然后像上面一样从 messagesAdded() 重新调用。

private void startImapIdle() {
    SimpleLogger.info("Idling now");

    Runnable r = () -> {
        try {
            inboxFolder.idle(false);
        } catch (FolderClosedException e) {
            SimpleLogger.warn("Push Error: [DISCONNECT]", e);
            GeneralUtility.threadSleep(mailListenerRetryInterval);
            startListening(inboxFolder);
        } catch (StoreClosedException e) {
            SimpleLogger.warn("Push Error: [GLOBAL DISCONNECT]", e);
            GeneralUtility.threadSleep(mailListenerRetryInterval);
            initConnection();
        } catch (MessagingException e) {
            SimpleLogger.warn("Push Error: [NO IDLE]", e);
            GeneralUtility.threadSleep(mailListenerRetryInterval);
            initConnection();
        } catch (Exception e) {
            SimpleLogger.warn("Push Error: [UNKNOWN]", e);
            GeneralUtility.threadSleep(mailListenerRetryInterval);
            initConnection();
        }
    };

    imapIdleThread = new Thread(r);
    imapIdleThread.start();
}

编辑:(新代码)

   private void startImapIdle() {
        while(true) {
            try {
                SimpleLogger.info("Idling now");
                MailUtility.ensureFolderOpen(folder);
                folder.idle();
            } catch (FolderClosedException e) {
                SimpleLogger.warn("Push Error: [DISCONNECT]", e);
                GeneralUtility.threadSleep(mailListenerRetryInterval);
                startListening();
                break;
            } catch (StoreClosedException e) {
                SimpleLogger.warn("Push Error: [GLOBAL DISCONNECT]", e);
                GeneralUtility.threadSleep(mailListenerRetryInterval);
                initConnection();
                break;
            } catch (MessagingException e) {
                SimpleLogger.warn("Push Error: [NO IDLE]", e);
                GeneralUtility.threadSleep(mailListenerRetryInterval);
                initConnection();
                break;
            } catch (Exception e) {
                SimpleLogger.warn("Push Error: [UNKNOWN]", e);
                GeneralUtility.threadSleep(mailListenerRetryInterval);
                initConnection();
                break;
            }
        }
    }

你是怎么做到的?下面的代码运行良好。

inbox.addMessageCountListener(new MessageCountAdapter() { ... })

当然你需要有另一个无限循环,比如:

          while (true) {
                  IMAPFolder f = (IMAPFolder)inbox;
                  f.idle();
          }