After the mail server receives the message, the service push notifies the program. Is there any way to achieve it?
1. Client Polling
2, the server initiative push.
First of all, get acquainted with the protocol for sending and receiving mail:
NET::SMTP (send mail)
Net::P OP3 (receiving mail)
Net::imap (Receive mail)
There are many examples of using POP3 to collect mail, but using POP3 to receive mail can only get all the messages in the Inbox, whether the message has been read and other tags can not be obtained, the use of IMAP protocol to avoid this embarrassment, IMAP can not only get the details of a message (such as whether read, reply) It also allows users to change the message's tag, but the current support IMAP protocol mail server is not much, I know only 21CN and Gmail, the following example uses the proxy, SSL authentication of multiple content, please refer to.
IMAP mail is all on demand, that is, when you get the object of a message, there is nothing in it, when you get the information in the object, such as Getsubject,
The message object then accesses the mail server again to get the message, so you cannot close the directory or disconnect it until you have all the information you need. If you really want to manipulate the message object after you close the directory or connect, you need to use the Fetch method of the folder object to get the information you need.
One: Client polling
Below, use POP3 and IMAP to display polling access to the example of getting mail:
POP3 Polling:
Copy Code code as follows:
Loop do
Require ' Net/pop '
Pop = Net::P op3.new (' Emailservice ')
Pop.start (' usename ', ' PASSWORD ')
If Pop.mails.empty?
Puts ' No mail. '
Else
Pop.each_mail do |m|
M.pop do |chunk|
P Chunk
End
End
Puts "#{pop.mails.size} mails popped."
End
Pop.finish
Sleep (10)
End
IMAP polling:
Copy Code code as follows:
Loop do
Require ' Net/imap '
IMAP = net::imap.new (' Emailservice ')
Imap.login "USERNAME", "PASSWORD"
Imap.examine (' INBOX ')
Imap.search (["Before", "29-oct-2014", "SINCE", "28-oct-2014"]). Each do |message_id|
Envelope = Imap.fetch (message_id, "envelope") [0].attr["Envelope"]
Puts "#{envelope.from[0].name}: \t#{envelope.subject}"
End
Sleep (10)
End
Two: Server initiative push
Below implementation of a server to push the way: (Imap.idle)
This is a technique between pull and persistent TCP/IP: Long polling (lengthy polling). The principle is that every time the client requests for services are serviced hold, wait until there is a message back or out, will again initiate the request, waiting for message arrival. This mode does not need to maintain the heartbeat, also does not need the persistent TCP the occupation, compared to the page end timely message's push.
Copy Code code as follows:
SERVER = ' Emailservice '
USERNAME = ' USERNAME '
PW = ' PASSWORD '
Require ' Net/imap '
# Extend support for idle command. Online.
# http://www.ruby-forum.com/topic/50828
# https://gist.github.com/jem/2783772
# but that is wrong. See/opt/ruby-1.9.1-p243/lib/net/imap.rb.
Class Net::imap
def Idle
cmd = "IDLE"
Synchronize do
@idle_tag = Generate_tag
Put_string (@idle_tag + "" + cmd)
Put_string (CRLF)
End
End
def Say_done
cmd = "Done"
Synchronize do
Put_string (CMD)
Put_string (CRLF)
End
End
def await_done_confirmation
Synchronize do
Get_tagged_response (@idle_tag, nil)
Puts ' just got confirmation '
End
End
End
Class Remailer
Attr_reader:imap
Public
DEF initialize
@imap = Nil
@mailer = Nil
Start_imap
End
def tidy
Stop_imap
End
def print_pust
Envelope = @imap. Fetch ( -1, "envelope") [0].attr["Envelope"]
Puts "from:#{envelope.from[0].name}\t Subject: #{envelope.subject}"
End
def Bounce_idle
# bounces the idle command.
@imap. Say_done
@imap. await_done_confirmation
# do a manual check, just in case things aren ' t working properly.
@imap. Idle
End
Private
def Start_imap
@imap = net::imap.new (' pop.i-click.com ')
@imap. Login USERNAME, PW
@imap. Select ' INBOX '
# ADD Handler.
@imap. Add_response_handler do |resp|
If resp.kind_of? (net::imap::untaggedresponse) and resp.name = "EXISTS"
@imap. Say_done
Thread.new do
@imap. await_done_confirmation
Print_pust
@imap. Idle
End
End
End
@imap. Idle
End
def Stop_imap
@imap. Done
End
End
Begin
Net::imap.debug = True
r = Remailer.new
Loop do
Puts ' bouncing ... '
R.bounce_idle
Sleep 15*60
#Generally set 15 minutes without operation to keep long links
End
Ensure
R.tidy
End