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