Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A common mistake is to assume an IDLE command will keep posting updates indefinitely. However, the <a href="http://tools.ietf.org/html/rfc2177">RFC 2177</a>, that defines the IDLE extension states:</p> <blockquote> <p>The server MAY consider a client inactive if it has an IDLE command running, and if such a server has an inactivity timeout it MAY log the client off implicitly at the end of its timeout period. Because of that, clients using IDLE are advised to terminate the IDLE and re-issue it at least every 29 minutes to avoid being logged off. This still allows a client to receive immediate mailbox updates even though it need only "poll" at half hour intervals.</p> </blockquote> <p>GMail in particular, has a much lower timeout, as you say, around 10 minutes.</p> <p>We simply need to reissue the IDLE command every 9 minutes or so for it to work. The <code>javax.mail</code> APIs have no way to set a timeout for the IDLE command, so you will need a second thread to move around this.</p> <p>A first approach would be to have the second thread interrupt the first one, handling the exception and ignoring it. This however, would allow for no clean way to shutdown the thread, so I won't recomend it. A much cleaner way is to have the second thread issue a NOOP command to the server. This does nothing at all, but is enough to have IDLE abort and be reissued.</p> <p>I here provide some code to do this:</p> <pre><code>public void startListening(IMAPFolder imapFolder) { // We need to create a new thread to keep alive the connection Thread t = new Thread( new KeepAliveRunnable(imapFolder), "IdleConnectionKeepAlive" ); t.start(); while (!Thread.interrupted()) { LOGGER.debug("Starting IDLE"); try { imapFolder.idle(); } catch (MessagingException e) { LOGGER.warn("Messaging exception during IDLE", e); throw new RuntimeException(e); } } // Shutdown keep alive thread if (t.isAlive()) { t.interrupt(); } } /** * Runnable used to keep alive the connection to the IMAP server * * @author Juan Martín Sotuyo Dodero &lt;jmsotuyo@monits.com&gt; */ private static class KeepAliveRunnable implements Runnable { private static final long KEEP_ALIVE_FREQ = 300000; // 5 minutes private IMAPFolder folder; public KeepAliveRunnable(IMAPFolder folder) { this.folder = folder; } @Override public void run() { while (!Thread.interrupted()) { try { Thread.sleep(KEEP_ALIVE_FREQ); // Perform a NOOP just to keep alive the connection LOGGER.debug("Performing a NOOP to keep alvie the connection"); folder.doCommand(new IMAPFolder.ProtocolCommand() { public Object doCommand(IMAPProtocol p) throws ProtocolException { p.simpleCommand("NOOP", null); return null; } }); } catch (InterruptedException e) { // Ignore, just aborting the thread... } catch (MessagingException e) { // Shouldn't really happen... LOGGER.warn("Unexpected exception while keeping alive the IDLE connection", e); } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload