我有一个跨越pcntl_fork()
新工作的工作者,我想在每个孩子中重复使用相同的连接,而不需要每个孩子每次重新连接,目标是获得巨大的性能提升。
我想阻止编号3.这样下一个孩子就可以重用套接字而无需重新连接,因为你知道SMTP协议很繁琐,需要时间重新连接。 SMTP服务器可能是sendmail / sendgrid / Gmail,我试过多个提供商,问题出在我的PHP而不是SMTP协议中。
我读到信号可能会导致流关闭。有没有办法可以防止这种情况发生。
我的选择是什么?
我正在使用PHPMailer,我删除了close from destructor。我已激活SMTPKeepAlive
,但没有帮助,正如您在附加的回购示例中所看到的那样。如果我使用的是PHP 5.4
更新1
我已将示例代码添加到此公共仓库:https://github.com/pentium10/php_stream_socket_test,您可以在http://www.dispostable.com/inbox/test/
检查可处置的收件箱您可以在repo的README文件中找到输出和SMTP响应。我确认从fork / child / exit调用中删除了任何内容,该示例可以工作并一个接一个地发送多个消息。
答案 0 :(得分:2)
在对您提供的代码进行一些调查后,看起来您的问题出现在启用TLS时。
如果您禁用以下行:
$mail->SMTPSecure = 'tls';
您的代码将按预期工作(只要您的smtp服务器接受不安全的连接)。
所以这绝对是不是套接字也不是分叉问题,但可能违反TLS协议。
如果您尝试发送RSET动词(例如,在$mail->getSMTPInstance()->reset();
呼叫之前呼叫email()
),则发送第二封邮件时的错误更清楚:
2014-11-04 00:23:18 SMTP ERROR: RSET command failed:
2014-11-04 00:23:18 SMTP NOTICE: EOF caught while checking if connected
我不是加密专家,所以我无法进一步发展。但我非常确定stream_socket_client使用的资源(并包含stream_socket_enable_crypto)存储了执行下一个TLS事务所需的一些上下文信息。在从第一个孩子发送电子邮件之后,资源的上下文在孩子的记忆中是最新的,但不在父母的记忆中。因此,当您尝试使用旧的上下文发送另一封电子邮件时,TLS会中断。