Hello folks,
I'm using Mail::IMAPClient to write my own mail monitor and currently trying handling connection problems, simulated simply detaching the ethernet cable. Ideally I'd like the program to retry a connection for some times before giving definitevely up.
With both intuitive solution like $imap->connect() if $imap->IsUnconnected and also reinstanciating the whole $imap object ( new calls connect or login on its own) I get a nasty loop of: Lost connection to ... retry 1 retry 2.. [I plug eth] Succesfully reconnected .. Lost connection to ..
Here the code reduced to the minimum (I left the read password echo(0) to play nicely with your terminal security ;)
use strict;
use warnings;
use Mail::IMAPClient;
use Term::ReadKey;
my $user = 'put.here.your.imap.account@example.com';
my $server = 'email.example.com';
my $port = 993;
my $ssl = 1; # generally ssl is used
my $imap_folder = "INBOX";
my $sleep = 5;
print "\n(use CTRL-C to permit logout)\n";
print "Enter the password for $user on $server\n";
my $password;
ReadMode('noecho');
$password = ReadLine(0);
chomp $password;
ReadMode 'normal';
my $imap = Mail::IMAPClient->new(
Server => $server,
User => $user,
password => $password,
Port => $port,
Ssl=> $ssl,
Uid=> 1,
) or die "IMAP Failure: $@";
print "Logged in succesfully\n" if $imap->IsConnected();
# Handle Ctrl-C
$SIG{INT} = sub{
print "\n\nLogging out..\n";
$imap->logout();
exit;
};
# do NOT mark as read when handling messages
$imap->Peek(1);
# look in INBOX
$imap->select( $imap_folder ) or die "IMAP Select Error for imap folde
+r [$imap_folder]: $@";
my $now = time;
my %seen = map { $_ => 1} $imap->sentsince($now);
while (1){
##################################################################
+##############
# Handling a lost connection
##################################################################
+##############
if ( $imap->IsUnconnected ){
print "Lost connection to $server\n";
for (1..100){
sleep 1 for 1..5;
print "Connection retry $_..\n";
# option 1
# enters in a loop connected / unconnected
# $imap->connect();
# option 2
# also this enters in a loop
$imap = Mail::IMAPClient->new(
Server => $server,
User => $user,
password => $password,
Port => $port,
Ssl=> $ssl,
Uid=> 1,
);
next unless $imap;
last if $imap->IsConnected();
}
# give up..
die "Reconnection impossible!" if $imap->IsUnconnected();
# if here we succeded
print "Succesfully reconnected!\n";
}
# as the above solutions do not work..
next if $imap->IsUnconnected();
##################################################################
+##############
my @msgs = $imap->sentsince($now);
foreach my $msg (@msgs){
# without this line I get an undef $msg entry in %seen
next unless defined $msg;
next if $seen{$msg};
$seen{ $msg }++;
print "New message: ",
$imap->get_header( $msg, "Subject" ), " from: ",
$imap->get_header( $msg, "From" ),"\n";
}
sleep 1 for 1..$sleep;
$now = time;
}
Some idea on how reconnect safely and really?
L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.