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

huangapple go评论82阅读模式
英文:

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

问题

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

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

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

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

 Reset发送RSET命令到服务器,中止当前的邮件事务。

我不想中止当前的邮件事务,我想要多个邮件事务。

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

英文:

I'm writing a package which I intend to make one initial connection to the local SMTP server and then it waits on a channel which will be populated with emails to send when they are needed to be sent.

Looking at net/http it appears to be expecting that the SMTP server should be dialed into and authenticated each time an email is to be sent. Surely I can dial and authenticate once, keep the connection open and just add new emails as they come?

Looking at the source for smtp.SendMail, I don't see how this can be done, as there does not appear to be a way to recycle the *Client:
http://golang.org/src/net/smtp/smtp.go?s=7610:7688#L263

There is a Reset function for *Client, but the description for that is:

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

I don't want to abort the current mail transaction, I want to have multiple mail transactions.

How can I keep the connection to the SMTP server open and send multiple emails on that one connection?

答案1

得分: 9

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

如果你想要更精细的控制,你应该使用持久的客户端连接。这将需要对smtp命令和协议有一定的了解。

  1. 使用smtp.Dial打开一个连接并创建一个客户端对象。
  2. 根据需要使用client.Helloclient.Authclient.StartTLS
  3. 使用RcptMailData等适当的方法发送消息。
  4. 当所有操作完成后,使用client.Quit()关闭连接。
英文:

You are correct that smtp.SendMail does not provide a way to reuse the connection.

If you want that fine grained control, you should use a persistent client connection. This will require knowing a bit more about the smtp commands and protocol.

  1. Use smtp.Dial to open a connection and create a client object.
  2. Use client.Hello, client.Auth, and client.StartTLS as appropriate.
  3. Use Rcpt, Mail, Data as approprate to send messages.
  4. client.Quit() and close connection when you are all done.

答案2

得分: 3

Gomail v2现在支持在一个连接中发送多封电子邮件。文档中的Daemon示例似乎符合您的用例:

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)
            }
        // 如果在最后30秒内没有发送电子邮件,则关闭与SMTP服务器的连接。
        case <-time.After(30 * time.Second):
            if open {
                if err := s.Close(); err != nil {
                    panic(err)
                }
                open = false
            }
        }
    }
}()

// 在您的程序中使用该通道发送电子邮件。

// 关闭通道以停止邮件守护进程。
close(ch)
英文:

Gomail v2 now supports sending multiple emails in one connection. The Daemon example from the documentation seems to match your use case:

ch := make(chan *gomail.Message)

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

	var s gomail.SendCloser
	var err error
	open := false
	for {
		select {
		case m, ok := &lt;-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 &lt;-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)

huangapple
  • 本文由 发表于 2015年5月26日 13:35:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/30450221.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定