英文:
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命令和协议有一定的了解。
- 使用
smtp.Dial
打开一个连接并创建一个客户端对象。 - 根据需要使用
client.Hello
、client.Auth
和client.StartTLS
。 - 使用
Rcpt
、Mail
、Data
等适当的方法发送消息。 - 当所有操作完成后,使用
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.
- Use
smtp.Dial
to open a connection and create a client object. - Use
client.Hello
,client.Auth
, andclient.StartTLS
as appropriate. - Use
Rcpt
,Mail
,Data
as approprate to send messages. 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("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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论