workerman 定时器中的任务执行失败了,怎么做异常处理?

ss7424

我使用了thinkphp5.0在id=0的进程上创建了一个查询数据的邮件内容,定时发送邮件的任务.

worker.php如下:

namespace app\push\controller;

use think\worker\Server;

use Workerman\Lib\Timer;
use think\Log;

class Worker extends Server
{
    protected $socket = 'websocket://0.0.0.0:2344';

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {
    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {

        // 只在id编号为0的进程上设置定时器,其它1、2、3号进程不设置定时器
        if($worker->id === 0) {
            Timer::add(2, function()use($worker){
                Log::record('[Worker][id][1][SendMail]');
                $watcher = controller('tasks/MailMan');
                $watcher->dog();
            });
        }
    }
}

task/MailMan执行的任务内容如下:

namespace app\tasks\controller;

use ext\MailTemplate;
use think\Db;
use think\Exception;
use think\Loader;
use think\Log;
Loader::import('lib.swift_required');
use Swift_SmtpTransport;
use Swift_Mailer;
use Swift_Message;

class MailMan {

    public function dog() {

        try {
            Log::record('[MailMan] start');

            $res = Db::table('ems_mail_queue')->where('to', '<>', '[]')
                ->order('id')->select();

            foreach ($res as $key => $item) {
                if (FLOW == $item['type']) {
                    $content = MailTemplate::getContent($item['main_body'], $item['table_data']);
                    $cc = config('mail_cc');
                } else {
                    $content = MailTemplate::getImportContent($item['main_body'], $item['table_data']);
                    $cc = config('mail_import_cc');
                }

                Log::record($content);
                $r = self::send($item['from'], json_decode($item['to'], true), $cc,
                    $item['subject'], $content);

                if ($r > 0) {
                    Log::record('[MailMan][dog] success ' .$item['id']);

                    // 删除该条记录
                    Db::table('ems_mail_queue')->where('id', $item['id'])->delete();

                } else {
                    Log::record('[MailMan][dog] fail ' .$item['id']);
                }

            }
        } catch (Exception $e) {
            Log::record('[MailMan][dog] error' . $e->getMessage());
        }

        Log::record('[MailMan] end');
    }

    // 发送邮件function
    private static function send($from, $to, $cc, $mailTitle, $content) {

        $transport = Swift_SmtpTransport::newInstance(config('smtp_host'), config('smtp_port'));

        $mailer = Swift_Mailer::newInstance($transport);

        // Create a message
        $message = Swift_Message::newInstance($mailTitle)
            ->setFrom(array($from))
            ->setTo($to) // 这里也是需要数组的
            ->setCc(json_decode($cc, true))
            ->setBody($content, 'text/html', 'utf-8');

        // Send the message
        $result = $mailer->send($message);
        return $result;
    }
}

我碰到的是如果MailMan.php中的$item['from']或者$item['to']的数据不对,也就是发件人或者收件人的地址不对,导致邮件发送不出去报错了.怎么才能控制异常,执行$res下一条数据?

如下图.我启动的server.php执行的时候像是碰到了异常,会终止该进程号重新开启一个新的workman进程号?

php server.php start执行中的错误

3210 2 0
2个回答

小阳光

自己捕获异常呀,把异常处理掉,也可以验证一下你的邮箱地址。

  • 暂无评论
ss7424

我改掉邮件发送异常捕捉的方式了.

try {
     $r = self::send($item['from'], json_decode($item['to'], true), $cc,
         $item['subject'], $content);

     if ($r > 0) {
         Log::record('[MailMan][dog] success ' .$item['id']);

         // 删除该条记录
         Db::table('ems_mail_queue')->where('id', $item['id'])->delete();
     }
 } catch (Swift_RfcComplianceException $e) {
     Log::record('[MailMan][dog] fail ' .$item['id'] .' '.$e->getMessage());
 }
  • 暂无评论
年代过于久远,无法发表回答
🔝