异步邮件新招:Asynchronous mail插件

Asynchronous mail是一个异步发送邮件的Grails插件。它将邮件相关参数以及内容持久化到数据库中,并且在一个scheduled任务中发送消息。如果SMTP服务器不可用,插件就会按照设置的时间间隔进行发送尝试,直到邮件成功发送或者过期。它依赖HibernateQuartzMail插件。

安装插件

安装Asynchronous mail插件,命令如下:grails install-plugin asynchronous-mail。

配置Mail插件

在Config.groovy文件中添加Mail插件相关的配置信息,比如我们使用Gmail服务器发送邮件,配置如下:

grails {
  mail {
    host = "smtp.gmail.com"
    port = 465
    username = "youracount@gmail.com"
    password = "yourpassword"
    props = ["mail.smtp.auth":"true", 					   
        "mail.smtp.socketFactory.port":"465",
        "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
        "mail.smtp.socketFactory.fallback":"false"]
  }
}

这里用到了Mail配置的一种方式,关于Mail插件的更多的配置方法,请参见Mail插件文档

配置Asynchronous mail插件

进行邮件的异步发送时,需要知道异步发送的相关参数,比如发送尝试的时间间隔,每条消息尝试发送的最大次数等等。如下是配置Asynchronous mail插件的两种方式:

  • 执行grails install-asynchronous-mail-config,在grails-app/config目录下创建AsynchronousMailConfig.groovy,可以根据实际情况修改这个文件中的参数值;
  • 或者直接使用plugin-dir/grails-app/conf/下的缺省DefaultAsynchronousMailConfig.groovy。

Asynchronous mail插件的缺省配置参数如下:

// 发送尝试的间隔时间,单位毫秒;
asynchronous.mail.default.attempt.interval=300000l    

//每个消息发送尝试的最大次数;
asynchronous.mail.default.max.attempts.count=1     

//重复启动发送任务的时间间隔,单位毫秒;
asynchronous.mail.send.repeat.interval=60000l  

//重复启动收集过期任务(如果发送时间过期了,就给消息打上过期的标记)的时间间隔,单位毫秒
asynchronous.mail.expired.collector.repeat.interval=607000l 

//一次能够发送的最大消息个数
asynchronous.mail.messages.at.once=100  

//如果为true,会在消息创建后立刻运行发送任务。缺省值为true
asynchronous.mail.send.immediately=true                   

配置Asynchronous mail使用的数据库,这个很简单,只需要在grails-app/config/DataSource.groovy中配置即可。这样在启动应用之后,会在数据库中创建相关数据表。参见下图:

异步发送邮件

在你自己的代码中注入Grails服务:AsynchronousMailService。示例代码如下:

class MailController {
  def asynchronousMailService
    def index = { 
      asynchronousMailService.sendAsynchronousMail {        
        to 'groovy.land@hotmail.com'
        subject 'Test';
        html 'Test';
        attachBytes 'test.txt', 'text/plain',AttachFile ContentBytes);
        // 附加的异步参数
        // 在一分钟后启动,缺省是当前时间启动
        beginDate new Date(System.currentTimeMillis()+60000)
        // 必须在一小时内发送,缺省是无穷大
        endDate new Date(System.currentTimeMillis()+3600000) 
        //尝试发送的最大次数为3,缺省值为1
        maxAttemptsCount 3; 
        //尝试发送的时间间隔,缺省为5分钟
        attemptInterval 300000;
      }
    }
}

这里需要注意,attachBytes的参数为附件名(String)、附件的MIME-type(String)、附件内容(byte[])。其中附件内容对应的字段类型为TinyBlob,而Tinyblog的最大长度为256字节。这就限制了附件内容长度不能超过256字节。可以通过修改plugin-dir/grails-app/domain/AsynchronousMailAttachment.groovy中的内容,将这个字段的类型变成BLOB、MEDIUMBLOB或者LONGBLOB,修改方法参见《Grails 1.2参考文档速读(9):GORM的高级特性及其他》

关于异步:邮件的状态分为CREATED, ATTEMPTED, SENT, ERROR, EXPIRED, ABORT。发送邮件之后,如果Gmail服务器不可用,那么邮件的状态就会是ATTEMPTED,之后会根据设置时间间隔进行尝试发送。一旦邮件发送成功,邮件的状态就会变更为SENT。

关于这个插件更多介绍,参见Asynchronous mail插件文档

By huwh - Posted on 17 四月 2010