zoukankan      html  css  js  c++  java
  • 异步发送邮件完整示例

    本章使用task异步进程进行邮件发送,来阐述一下以上章节提到的各个知识点。

    邮件类

    下载swiftmailer

    composer require "swiftmailer/swiftmailer:^6.0"
    

    Mailer.php 与 vender目录 同级

    require_once __DIR__ . '/vendor/autoload.php';
    
    class Mailer
    {
        public $transport;
        public $mailer;
        /**
         * 发送邮件类 参数 $data 需要三个必填项 包括 邮件主题`$data['subject']`、接收邮件的人`$data['to']`和邮件内容 `$data['content']`
         * @param Array $data
         * @return bool $result 发送成功 or 失败
         */
        public function send($data)
        {
            $this->transport = (new Swift_SmtpTransport('smtp.qq.com', 25))
                ->setEncryption('tls')
                ->setUsername('bailangzhan@qq.com')
                ->setPassword('xxxxxx');
            $this->mailer = new Swift_Mailer($this->transport);
    
            $message = (new Swift_Message($data['subject']))
                ->setFrom(array('bailangzhan@qq.com' => '白狼栈'))
                ->setTo(array($data['to']))
                ->setBody($data['content']);
                
            $result = $this->mailer->send($message);
    
            // 释放
            $this->destroy();
            return $result;
        }
        public function destroy()
        {
            $this->transport = null;
            $this->mailer = null;
        }
    }
    

    Server

    后端启动:php server.php
    这里单独拆分了一个TaskRun类,并且在onWorkerStart之后进行载入,主要是为了之后的“平滑重启“

    class TaskServer
    {
        private $_serv;
        private $_run;
    
        public function __construct()
        {
            $this->_serv = new Swoole\Server("127.0.0.1", 9501);
            $this->_serv->set([
                'worker_num' => 2,
                'daemonize' => false,    //是否开启守护进程
                'log_file' => __DIR__ . '/server.log',    //守护进程调试日志
                'task_worker_num' => 2,
                'max_request' => 5000,    //防止内存泄漏
                'task_max_request' => 5000,    //防止内存泄漏
                'package_eof' => "\r\n", //设置EOF
                'open_eof_split' => true, // 自动分包
            ]);
            $this->_serv->on('Connect', [$this, 'onConnect']);
            $this->_serv->on('Receive', [$this, 'onReceive']);
            $this->_serv->on('WorkerStart', [$this, 'onWorkerStart']);
            $this->_serv->on('Task', [$this, 'onTask']);
            $this->_serv->on('Finish', [$this, 'onFinish']);
            $this->_serv->on('Close', [$this, 'onClose']);
        }
        public function onConnect($serv, $fd, $fromId)
        {
        }
        public function onWorkerStart($serv, $workerId)
        {
            require_once __DIR__ . "/TaskRun.php";
            $this->_run = new TaskRun;
        }
        public function onReceive($serv, $fd, $fromId, $data)
        {
            $data = $this->unpack($data);
            $this->_run->receive($serv, $fd, $fromId, $data);
            // 投递一个任务到task进程中
            if (!empty($data['event'])) {
                $serv->task(array_merge($data , ['fd' => $fd]));
            }
        }
        public function onTask($serv, $taskId, $fromId, $data)
        {
            $this->_run->task($serv, $taskId, $fromId, $data);
        }
        public function onFinish($serv, $taskId, $data)
        {
            $this->_run->finish($serv, $taskId, $data);
        }
        public function onClose($serv, $fd, $fromId)
        {
        }
        /**
        * 对数据包单独处理,数据包经过`json_decode`处理之后,只能是数组
        * @param $data
        * @return bool|mixed
        */
        public function unpack($data)
        {
            $data = str_replace("\r\n", '', $data);
            if (!$data) {
                return false;
            }
            $data = json_decode($data, true);
            if (!$data || !is_array($data)) {
                return false;
            }
            return $data;
        }
        public function start()
        {
            $this->_serv->start();
        }
    }
    $reload = new TaskServer;
    $reload->start();
    

    TaskRun 业务类

    当此处修改了代码后,可以进行平滑重启,因为他是在Server端的onWorkerStart之后加载的文件。

    require_once ('./Mailer.php');
    class TaskRun
    {
        public function receive($serv, $fd, $fromId, $data)
        {
        }
        public function task($serv, $taskId, $fromId, $data)
        {
            try {
                switch ($data['event']) {
                    case 'send-mail':
                        $mailer = new Mailer;
                        $result = $mailer->send($data);
                        break;
                    default:
                        break;
                }
                return $result;
            } catch (\Exception $e) {
                throw new \Exception('task exception :' . $e->getMessage());
            }
        }
        public function finish($serv, $taskId, $data)
        {
            return true;
        }
    }
    

    Client

    client加了eof,为了防止粘包,通过网址访问该程序

    $client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
    
    $client->connect('127.0.0.1', 9501) || exit("connect failed. Error: {$client->errCode}\n");
    
    $data = [
        'event' => 'send-mail',
        'to' => '5566***@qq.com',
        'subject' => 'just a test',
        'content' => 'This just a test.',
    ];
    
    $client->send(togetherDataByEof($data));    //发送数据给服务端
    
    $client->close();   //关闭连接
    
    /**
     * 数据末尾拼接EOF标记
     * @param Array $data 要处理的数据
     * @return String json_encode($data) . EOF
     */
    function togetherDataByEof($data)
    {
        if (!is_array($data)) {
            return false;
        }
        return json_encode($data) . "\r\n";
    }

  • 相关阅读:
    好文!悟透JavaScript
    关于“四舍六入五成双/四舍六入五留双/四舍六入五单双”等口诀的实例研究
    第四个:怎么应付在背地里说你坏话的人
    为什么日全食时开始下雨,10分钟后雨又停了。初中物理知识。
    吃萝卜去口气(口臭)
    今天12点34分56秒是一个神奇的时刻
    sharepoint2010人性化的地方员工离职AD账号禁用(个人网站自动提醒上级经理功能)
    指定为添加到网站中的项目显示“新”图标的天数。
    解决sharepoint2010的多行文本框的插入图片—【从sharepoint】的disabled问题
    sharepoint2010的IE6不支持的解决方法
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15452913.html
Copyright © 2011-2022 走看看