java mail 实现邮件的推送

今天在做邮件的推送功能,即当邮件服务器接收到新邮件时,客户端这边可以立即接收到。

思路:利用 Java Mail IMAP IDLE 去实现此功能

刚开始利用 folder.idle()去实现,代码如下,但出现一个问题,接收到新邮件之后,会自动断开监听。

 IMAPFolder folder = (IMAPFolder)store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        folder.addMessageCountListener(new MessageCountAdapter() {
            @Override
            public void messagesAdded(MessageCountEvent e) {
                super.messagesAdded(e);
                Message[] msgs = e.getMessages();
                for(int i=0;i<msgs.length;i++){
                    try {
                        Log.e("add 邮件","add 邮件主题"+msgs[i].getSubject());
                    } catch (MessagingException e1) {
                        e1.printStackTrace();
                    }
                }
               
            }

            @Override
            public void messagesRemoved(MessageCountEvent e) {
                super.messagesRemoved(e);
                Message[] msgs = e.getMessages();
                for(int i=0;i<msgs.length;i++){
                    try {
                        Log.e("remove 邮件","remove 邮件主题"+msgs[i].getSubject());
                    } catch (MessagingException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        });
        folder.idle(true);

 查看官方文档:

Google翻译:与idle()类似,但如果一次为真,则在第一次通知后中止IDLE命令,以允许调用者同步处理任何通知。

然后我就用folder.idle()去替代folder.idle(true),但貌似还是没起作用,下面是idle()方法的介绍

Google翻译:如果服务器支持,则使用IMAP IDLE命令(请参阅RFC 2177)进入空闲模式,以便服务器可以发送未经请求的新消息到达等通知,而无需客户端不断轮询服务器。 使用适当的侦听器来通知新消息或其他事件。 当另一个线程(例如,侦听器线程)需要为该文件夹发出IMAP命令时,将终止空闲模式并返回此方法。 通常,调用者将在循环中调用此方法。
mail.imap.minidletime属性在从此方法返回之前强制执行最小延迟,以确保其他线程有机会在调用者再次调用此方法之前发出命令。 默认延迟为10毫秒。

最后如何解决的:

利用IdleManager迅速解决了此问题(查阅了官网文档)

 ExecutorService es = Executors.newCachedThreadPool();
        final IdleManager idleManager = new IdleManager(session, es);
        IMAPFolder folder = (IMAPFolder)store.getFolder("INBOX");
        folder.open(Folder.READ_WRITE);
        folder.addMessageCountListener(new MessageCountAdapter() {
            @Override
            public void messagesAdded(MessageCountEvent e) {
                super.messagesAdded(e);
                Folder folder = (Folder)e.getSource();
                Message[] msgs = e.getMessages();
                for(int i=0;i<msgs.length;i++){
                    try {
                        Log.e("add 邮件","add 邮件主题"+msgs[i].getSubject());
                    } catch (MessagingException e1) {
                        e1.printStackTrace();
                    }
                }
                try {
                    idleManager.watch(folder);
                } catch (MessagingException e1) {
                    e1.printStackTrace();
                }
            }

            @Override
            public void messagesRemoved(MessageCountEvent e) {
                super.messagesRemoved(e);
                Message[] msgs = e.getMessages();
                for(int i=0;i<msgs.length;i++){
                    try {
                        Log.e("remove 邮件","remove 邮件主题"+msgs[i].getSubject());
                    } catch (MessagingException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        });
        idleManager.watch(folder);

 目前此方法测试良好,但可能会出现断线重连的状况,IMAP指出30分钟内无任何响应,会自动断开连接,所以这个问题我们也得重视。

猜你喜欢

转载自blog.csdn.net/qq_35644307/article/details/84396846