我希望“尽快”获取看不见的邮件,使用Ruby(2.1)脚本实现IMAP IDLE(“推送通知”)功能。
在一些人的帮助下(另见:Support for IMAP IDLE in ruby),我在这里编写了脚本: https://gist.github.com/solyaris/b993283667f15effa579
def idle_loop(imap, search_condition, folder)
# https://stackoverflow.com/questions/4611716/how-imap-idle-works
loop do
begin
imap.select folder
imap.idle do |resp|
#trap_shutdown
# You'll get all the things from the server.
#For new emails you're only interested in EXISTS ones
if resp.kind_of?(Net::IMAP::UntaggedResponse) and resp.name == "EXISTS"
# Got something. Send DONE. This breaks you out of the blocking call
imap.idle_done
end
end
# We're out, which means there are some emails ready for us.
# Go do a search for UNSEEN and fetch them.
retrieve_emails(imap, search_condition, folder) { |mail| process_email mail}
#rescue Net::IMAP::Error => imap_err
# Socket probably timed out
# puts "IMAP IDLE socket probably timed out.".red
rescue SignalException => e
# https://stackoverflow.com/questions/2089421/capturing-ctrl-c-in-ruby
puts "Signal received at #{time_now}: #{e.class} #{e.message}".red
shutdown imap
rescue Exception => e
puts "Something went wrong at #{time_now}: #{e.class} #{e.message}".red
imap.noop
end
end
end
现在,乍看之下一切顺利,但我有例外
出了点问题:SSL_write:错误的写入重试
代码中的这一行: https://gist.github.com/solyaris/b993283667f15effa579#file-idle-rb-L189
当我让脚本运行超过30分钟时,会发生错误。
顺便说一句,服务器是imap.gmail.com(arghh ...),我认为是与IMAP IDLE重新连接套接字相关的东西(我还没读过ruby UMAP库代码)但是我不明白例外的原因;任何想法,如果例外?只是捕获异常以解决问题?
感谢 乔治
更新
我修改了一点异常处理(参见gist代码:https://gist.github.com/solyaris/b993283667f15effa579)
现在我得到一个Net::IMAP::Error connection closed
我只是重启IMAP连接,它似乎正在工作......
很抱歉让人感到困惑,总的来说,对我编写的代码,IDLE协议正确管理的任何评论一般,欢迎。
答案 0 :(得分:1)
IMAP IDLE RFC表示在最多29分钟后停止IDLE并重新发出新的IDLE命令。允许IMAP服务器假设客户端已经死亡,并且在31分钟不活动后已经离开。
你可能还会发现一些NAT中间件在半小时之前很久就默默地破坏了你的连接,我看到超时只有两分钟左右。 (每当我看到类似的东西时,我尖叫“vivat ipv6!”)我不认为这些中间盒有任何好的解决方案,除了可能用邪恶的木马感染它们,但不好的解决方案包括调整你的空闲超时如果你在半小时之前获得SSL异常。