gpt4 book ai didi

JavaMail : Keeping IMAPFolder. 闲置()还活着

转载 作者:搜寻专家 更新时间:2023-10-30 19:54:48 25 4
gpt4 key购买 nike

我正在制作一个需要监视 Gmail 帐户是否有新邮件的程序,为了尽快收到它们,我正在使用 JavaMail 的闲置功能。这是我用来调用 folder.idle() 的线程中的代码片段:

//Run method that waits for idle input. If an exception occurs, end the thread's life.
public void run() {

IMAPFolder folder = null;

try {
folder = getFolder();
while(true)
{
//If connection has been lost, attempt to restore it
if (!folder.isOpen())
folder = getFolder();
//Wait until something happens in inbox
folder.idle(true);
//Notify controller of event
cont.inboxEventOccured();
}
}
catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("MailIdleWaiter thread ending.");
}

getFolder() 方法主要是打开与 IMAP 服务器的连接并打开收件箱。

这工作了一段时间,但在 10 分钟左右后它停止获取更新(没有抛出异常)。

我正在寻找保持连接有效的建议。我是否需要第二个线程,其唯一作用是每 10 分钟 hibernate 并更新 idle() 线程,还是有更简单/更好的方法?

提前致谢。

最佳答案

一个常见的错误是假设 IDLE 命令会无限期地发布更新。然而,RFC 2177 ,它定义了 IDLE 扩展状态:

The server MAY consider a client inactive if it has an IDLE commandrunning, and if such a server has an inactivity timeout it MAY logthe client off implicitly at the end of its timeout period. Becauseof that, clients using IDLE are advised to terminate the IDLE andre-issue it at least every 29 minutes to avoid being logged off.This still allows a client to receive immediate mailbox updates eventhough it need only "poll" at half hour intervals.

特别是 GMail,超时时间要短得多,如您所说,大约 10 分钟。

我们只需要每 9 分钟左右重新发出一次 IDLE 命令,它就可以工作了。 javax.mail API 无法为 IDLE 命令设置超时,因此您需要第二个线程来解决这个问题。

第一种方法是让第二个线程中断第一个线程,处理异常并忽略它。然而,这将不允许以干净的方式关闭线程,所以我不会推荐它。一种更简洁的方法是让第二个线程向服务器发出 NOOP 命令。这根本不执行任何操作,但足以让 IDLE 中止并重新发布。

我在这里提供了一些代码来做到这一点:

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 <jmsotuyo@monits.com>
*/
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);
}
}
}
}

关于JavaMail : Keeping IMAPFolder. 闲置()还活着,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4155412/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com