Go:连接到 SMTP 服务器并在一个连接中发送多封电子邮件?

Go: Connect to SMTP server and send multiple emails in one connection?

我正在编写一个包,我打算与本地 SMTP 服务器建立一个初始连接,然后它等待一个通道,该通道将填充电子邮件以在需要发送时发送。

查看 net/http 似乎期望每次发送电子邮件时都应拨入 SMTP 服务器并进行身份验证。我当然可以拨号和验证一次,保持连接打开并在收到新电子邮件时添加它们?

查看 smtp.SendMail 的源代码,我不知道如何做到这一点,因为似乎没有办法回收 *Clienthttp://golang.org/src/net/smtp/smtp.go?s=7610:7688#L263

*Client 有一个 Reset 函数,但其​​描述是:

 Reset sends the RSET command to the server, aborting the current mail transaction.

我不想中止当前的邮件交易,我想有多个邮件交易。

如何保持与 SMTP 服务器的连接打开并在该连接上发送多封电子邮件?

您是正确的,smtp.SendMail 没有提供重用连接的方法。

如果你想要细粒度的控制,你应该使用持久的客户端连接。这将需要更多地了解 smtp 命令和协议。

  1. 使用smtp.Dial打开连接并创建客户端对象。
  2. 酌情使用 client.Helloclient.Authclient.StartTLS
  3. 根据需要使用RcptMailData发送消息。
  4. client.Quit() 完成后关闭连接。

Gomail v2 现在支持在一个连接中发送多封电子邮件。文档中的 Daemon example 似乎与您的用例相匹配:

ch := make(chan *gomail.Message)

go func() {
    d := gomail.NewPlainDialer("smtp.example.com", 587, "user", "123456")

    var s gomail.SendCloser
    var err error
    open := false
    for {
        select {
        case m, ok := <-ch:
            if !ok {
                return
            }
            if !open {
                if s, err = d.Dial(); err != nil {
                    panic(err)
                }
                open = true
            }
            if err := gomail.Send(s, m); err != nil {
                log.Print(err)
            }
        // Close the connection to the SMTP server if no email was sent in
        // the last 30 seconds.
        case <-time.After(30 * time.Second):
            if open {
                if err := s.Close(); err != nil {
                    panic(err)
                }
                open = false
            }
        }
    }
}()

// Use the channel in your program to send emails.

// Close the channel to stop the mail daemon.
close(ch)