2014-12-14 13 views
1

Мне нравится получать невидимые письма «как можно скорее», используя скрипт Ruby (2.1) для реализации функции IMAP IDLE («push notify»).SSL_write: неудачная попытка повторной записи. Исключение. Чтение электронных писем с IMAP IDLE. В Ruby

С помощью некоторых ребят (смотрите также: 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 

Теперь все запустить smootly на первый взгляд, но у меня есть исключение

Что-то пошло не так: SSL_write: плохая запись повторных попыток

на этой линии в коде: https://gist.github.com/solyaris/b993283667f15effa579#file-idle-rb-L189

Ошибка возникает, когда я оставляю скрипт более чем на ... более 30 минут.

BTW, сервер imap.gmail.com (arghh ...), и я полагаю, что это связано с подключением повторного подключения IMAP IDLE (я еще не читал код библиотеки ruby ​​UMAP), но я не понимаю причина исключения;

Любая идея по причине исключения? Просто обманите исключение, чтобы исправить проблему?

благодаря Джорджио

UPDATE

Я изменил немного обработки исключений (см GIST код: https://gist.github.com/solyaris/b993283667f15effa579)

Теперь я получил Net::IMAP::Error connection closed я просто перезагрузить соединение по протоколу IMAP, и кажется, рабочий ... Извините за смущение, в любом случае, в общем, любые комментарии по коду, который я написал, правильное управление IDLE протоколом, приветствуются.

ответ

1

IMAP IDLE RFC заявляет о прекращении IDLE через не более 29 минут и переиздает новую команду IDLE. Серверм IMAP разрешено предположить, что клиент мертв и ушел после 31 минуты бездействия.

Вы также можете обнаружить, что некоторые межсетевые экраны NAT молча саботируют ваше соединение задолго до полутора часов, я видел, что тайм-ауты составляют около двух минут. (Каждый раз, когда я вижу что-то подобное, я кричу «vivat ipv6!»). Я не думаю, что есть хорошие решения для этих медиабоксов, за исключением, возможно, заражения их гнусным трояном, но плохие решения включают в себя настройку таймаута простоя, если вы получите исключение SSL до полутора часов.

+0

Да ... в случае сервера imap.gmail.com, я тестировал (см. Мой комментарий UPDATE в исходном вопросе) отключение в течение почти 1 часа. Я не знал о правиле RFC 29 минут. Теперь я понимаю, почему кто-то делает что-то вроде 'Thread.start {loop {imap.idle_done; sleep 600}} ', так что перезапуск IDLE каждые 10 минут ... спасибо –