正在显示
8 个修改的文件
包含
258 行增加
和
6 行删除
cmd/sync.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +//error_reporting(); | ||
| 4 | + | ||
| 5 | +use Swoole\Process; | ||
| 6 | + | ||
| 7 | + | ||
| 8 | + | ||
| 9 | +include_once __DIR__."/../vendor/autoload.php"; | ||
| 10 | + | ||
| 11 | + | ||
| 12 | +function start(){ | ||
| 13 | + | ||
| 14 | +// 删除停止运行的值 | ||
| 15 | + redis()->delete(RUNNING_REDIS_KEY); | ||
| 16 | + | ||
| 17 | + // 进程管理器 | ||
| 18 | + $pm = new Process\Manager(); | ||
| 19 | + | ||
| 20 | + // 启动一个进程来管理定时 | ||
| 21 | + $pm->add(function (Process\Pool $pool, int $workerId){ | ||
| 22 | + _echo("定时进程({$workerId})启动成功"); | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + // 进行阻塞,否则定时器无法运行 | ||
| 26 | + while (true){ | ||
| 27 | + co::sleep(9999); | ||
| 28 | + } | ||
| 29 | + },true); | ||
| 30 | + | ||
| 31 | + | ||
| 32 | +// 协程配置 | ||
| 33 | + \co::set([ | ||
| 34 | + 'max_coroutine'=>COROUTINE_MAX_NUM, // 最大携程数量 | ||
| 35 | + 'hook_flags'=>SWOOLE_HOOK_TCP, // redis需要的配置 | ||
| 36 | + ]); | ||
| 37 | + | ||
| 38 | + // 启动业务进程 | ||
| 39 | + $pm->addBatch(WORKER_NUM,function (Process\Pool $pool, int $worker_id){ | ||
| 40 | + _echo("业务进程({$worker_id})启动成功"); | ||
| 41 | + | ||
| 42 | + $start_num = 0;// 启动的协程数量 | ||
| 43 | + | ||
| 44 | + // 循环阻塞 | ||
| 45 | + while (true){ | ||
| 46 | + // 是否到了协程配置的数量上限 | ||
| 47 | + if($start_num < COROUTINE_MAX_NUM){ | ||
| 48 | + // 需要同步的id | ||
| 49 | + $id = redis()->lPop('sync_email_lists'); | ||
| 50 | + | ||
| 51 | + if(!$id){ | ||
| 52 | + co::sleep(1); | ||
| 53 | + }else{ | ||
| 54 | + // 启动一个协程 | ||
| 55 | + go(function () use (&$start_num,$worker_id,$id){ | ||
| 56 | + $start_num++; | ||
| 57 | + | ||
| 58 | + // 开始同步 | ||
| 59 | + try { | ||
| 60 | + sync($id,$worker_id); | ||
| 61 | + }catch (\Throwable $e){ | ||
| 62 | + // 重新发布同步任务,如果失败了是否重新发布 | ||
| 63 | + redis()->rPush('sync_email_lists',$id); | ||
| 64 | + | ||
| 65 | +// _echo($e->getMessage()); | ||
| 66 | + logs( | ||
| 67 | + $e->getMessage().PHP_EOL.$e->getTraceAsString(), | ||
| 68 | + LOG_PATH.'/'.$worker_id.'_'.co::getCid().'.log' | ||
| 69 | + ); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + // 协程完成后执行的函数 | ||
| 73 | + co::defer(function () use (&$start_num,$worker_id){ | ||
| 74 | +// _echo('正常关闭进程('.$worker_id.')下的协程('.co::getCid().')'); | ||
| 75 | + $start_num--; | ||
| 76 | + }); | ||
| 77 | + | ||
| 78 | + }); | ||
| 79 | + | ||
| 80 | + } | ||
| 81 | + }else{ | ||
| 82 | + // 协程到了最大的数量,阻塞1秒 | ||
| 83 | + co::sleep(1); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + | ||
| 90 | + },true); | ||
| 91 | + | ||
| 92 | + | ||
| 93 | + // 启动管理器 | ||
| 94 | + $pm->start(); | ||
| 95 | + | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | + | ||
| 99 | +/** | ||
| 100 | + * 开始同步, 这里是主要的业务代码 | ||
| 101 | + * @param $email_id | ||
| 102 | + * @param $worker_id | ||
| 103 | + * @return int | ||
| 104 | + * @author:dc | ||
| 105 | + * @time 2023/3/10 10:19 | ||
| 106 | + */ | ||
| 107 | +function sync($email_id,$worker_id){ | ||
| 108 | + | ||
| 109 | + $email = db()->first(\Model\emailSql::first($email_id)); | ||
| 110 | + if(!$email){ | ||
| 111 | + return 0; | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + if($email['pwd_error']){ | ||
| 115 | + return 1; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + $mailServer = new Lib\Mail\Mail(); | ||
| 119 | + | ||
| 120 | + try { | ||
| 121 | + // 登录服务器 | ||
| 122 | + $mailServer->login($email['email'],base64_decode($email['password']),$email['imap']); | ||
| 123 | + }catch (Throwable $e){ | ||
| 124 | + if($e->getCode() == 403){ | ||
| 125 | + // 登录失败了 , | ||
| 126 | + db()->update(\Model\emailSql::$table,['pwd_error'=>1],dbWhere(['id'=>$email_id])); | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + return 2; | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + // 同步文件夹 | ||
| 133 | + $mailServer->syncFolder($email_id,db()); | ||
| 134 | + | ||
| 135 | + | ||
| 136 | + // 读取到邮箱中的文件夹 | ||
| 137 | + $folders = db()->all(\Model\folderSql::all($email['id'])); | ||
| 138 | + if(!$folders){ | ||
| 139 | + return 3; | ||
| 140 | + } | ||
| 141 | + $folders = list_to_tree($folders); | ||
| 142 | + foreach ($folders as $folder){ | ||
| 143 | + try { | ||
| 144 | + if(empty($folder['_child'])){ | ||
| 145 | + // 同步父文件夹 | ||
| 146 | + $mailServer->syncMail($email_id,$folder['id'],$folder['origin_folder']); | ||
| 147 | + }else{ | ||
| 148 | + foreach ($folder as $item){ | ||
| 149 | + // 同步子文件夹 | ||
| 150 | + $mailServer->syncMail($email_id,$item['id'],$item['origin_folder']); | ||
| 151 | + } | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + }catch (Throwable $e){ | ||
| 155 | + logs( | ||
| 156 | + $e->getMessage(), | ||
| 157 | + LOG_PATH.'/imap/'.$email['email'].'.error.log' | ||
| 158 | + ); | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + | ||
| 163 | + $email = null; | ||
| 164 | + $mailServer = null; | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | + | ||
| 168 | + | ||
| 169 | + | ||
| 170 | +switch ($argv[1]){ | ||
| 171 | + case 'start':{ | ||
| 172 | + start(); | ||
| 173 | + break; | ||
| 174 | + } | ||
| 175 | + case 'stop':{ | ||
| 176 | + \Co\run(function (){ | ||
| 177 | + echo "正在退出程序...\n非必要请不要强制kill掉进程\n"; | ||
| 178 | + redis()->set(RUNNING_REDIS_KEY,'stop'); | ||
| 179 | + while (true){ | ||
| 180 | + $num = exec("ps -ef | grep \"sync.php start\" | grep -v grep | wc -l"); | ||
| 181 | + if(!$num){ | ||
| 182 | + break; | ||
| 183 | + } | ||
| 184 | + co::sleep(0.5); | ||
| 185 | + } | ||
| 186 | + echo "已退出程序\n"; | ||
| 187 | + }); | ||
| 188 | + break; | ||
| 189 | + } | ||
| 190 | + default:{ | ||
| 191 | + break; | ||
| 192 | + } | ||
| 193 | +} | ||
| 194 | + | ||
| 195 | + | ||
| 196 | + | ||
| 197 | + | ||
| 198 | + | ||
| 199 | + | ||
| 200 | + | ||
| 201 | + | ||
| 202 | + | ||
| 203 | + |
| @@ -3,9 +3,9 @@ | @@ -3,9 +3,9 @@ | ||
| 3 | error_reporting(E_ERROR | E_NOTICE); | 3 | error_reporting(E_ERROR | E_NOTICE); |
| 4 | 4 | ||
| 5 | // 开启4个进程 | 5 | // 开启4个进程 |
| 6 | -define('WORKER_NUM',2); | 6 | +define('WORKER_NUM',10); |
| 7 | // 开启最大1000个协程 | 7 | // 开启最大1000个协程 |
| 8 | -define('COROUTINE_MAX_NUM',1000); | 8 | +define('COROUTINE_MAX_NUM',5000); |
| 9 | // 是否继续运行 | 9 | // 是否继续运行 |
| 10 | define('RUNNING_REDIS_KEY','worker_is_running'); | 10 | define('RUNNING_REDIS_KEY','worker_is_running'); |
| 11 | // 记录日志的目录 | 11 | // 记录日志的目录 |
| @@ -3,6 +3,7 @@ | @@ -3,6 +3,7 @@ | ||
| 3 | namespace Controller; | 3 | namespace Controller; |
| 4 | 4 | ||
| 5 | 5 | ||
| 6 | +use Lib\Mail\Mail; | ||
| 6 | use Lib\Mail\MailFun; | 7 | use Lib\Mail\MailFun; |
| 7 | use Model\folderSql; | 8 | use Model\folderSql; |
| 8 | 9 | ||
| @@ -70,12 +71,41 @@ class Folder extends Base { | @@ -70,12 +71,41 @@ class Folder extends Base { | ||
| 70 | ] | 71 | ] |
| 71 | )); | 72 | )); |
| 72 | 73 | ||
| 74 | + if($has){ | ||
| 75 | + app()->e('folder_is_exist'); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + // 远程创建 | ||
| 79 | + $mail = new Mail(); | ||
| 80 | + $mail->login($this->login_email['email'],$this->login_email['password'],$this->login_email['imap']); | ||
| 81 | + $folder = $mail->client->folderCreate($formData['folder']); | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + | ||
| 73 | 85 | ||
| 74 | 86 | ||
| 75 | 87 | ||
| 76 | } | 88 | } |
| 77 | 89 | ||
| 78 | 90 | ||
| 91 | + /** | ||
| 92 | + * 改名 | ||
| 93 | + * @author:dc | ||
| 94 | + * @time 2023/3/3 17:40 | ||
| 95 | + */ | ||
| 96 | + public function rename(){ | ||
| 97 | + | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * 删除 | ||
| 102 | + * @author:dc | ||
| 103 | + * @time 2023/3/3 17:38 | ||
| 104 | + */ | ||
| 105 | + public function delete(){ | ||
| 106 | + | ||
| 107 | + } | ||
| 108 | + | ||
| 79 | 109 | ||
| 80 | 110 | ||
| 81 | 111 |
| @@ -258,7 +258,7 @@ function list_to_tree($list, $pk='id',$pid = 'pid',$child = '_child',$root=0,$em | @@ -258,7 +258,7 @@ function list_to_tree($list, $pk='id',$pid = 'pid',$child = '_child',$root=0,$em | ||
| 258 | * @author:dc | 258 | * @author:dc |
| 259 | * @time 2023/2/18 11:04 | 259 | * @time 2023/2/18 11:04 |
| 260 | */ | 260 | */ |
| 261 | -function start_now_mail(){ | 261 | +function start_now_mail($email=null){ |
| 262 | $id = 0; | 262 | $id = 0; |
| 263 | 263 | ||
| 264 | while (true){ | 264 | while (true){ |
| @@ -23,5 +23,6 @@ return [ | @@ -23,5 +23,6 @@ return [ | ||
| 23 | 'folder_create_name_error' => '文件夹名称只能输入中文英文数字', | 23 | 'folder_create_name_error' => '文件夹名称只能输入中文英文数字', |
| 24 | 'folder_parent_not_fount' => '上级文件夹不存在', | 24 | 'folder_parent_not_fount' => '上级文件夹不存在', |
| 25 | 'folder_tree_max_two' => '文件夹最多2级', | 25 | 'folder_tree_max_two' => '文件夹最多2级', |
| 26 | + 'folder_is_exist' => '文件夹已存在', | ||
| 26 | 27 | ||
| 27 | ]; | 28 | ]; |
| @@ -430,12 +430,12 @@ class Imap { | @@ -430,12 +430,12 @@ class Imap { | ||
| 430 | * 创建文件夹 | 430 | * 创建文件夹 |
| 431 | * $folder 目录 创建二级目录用/ a/b | 431 | * $folder 目录 创建二级目录用/ a/b |
| 432 | * @param string $folder | 432 | * @param string $folder |
| 433 | - * @return bool | 433 | + * @return string |
| 434 | * @throws \Exception | 434 | * @throws \Exception |
| 435 | * @author:dc | 435 | * @author:dc |
| 436 | * @time 2022/11/24 23:35 | 436 | * @time 2022/11/24 23:35 |
| 437 | */ | 437 | */ |
| 438 | - public function folderCreate(string $folder):bool { | 438 | + public function folderCreate(string $folder):string { |
| 439 | // 需要转码 | 439 | // 需要转码 |
| 440 | $folder = mb_convert_encoding($folder,'UTF7-IMAP','UTF-8'); | 440 | $folder = mb_convert_encoding($folder,'UTF7-IMAP','UTF-8'); |
| 441 | // A003 CREATE owatagusiam 顶级 | 441 | // A003 CREATE owatagusiam 顶级 |
| @@ -443,7 +443,7 @@ class Imap { | @@ -443,7 +443,7 @@ class Imap { | ||
| 443 | $res = $this->request('CREATE '.$folder); | 443 | $res = $this->request('CREATE '.$folder); |
| 444 | 444 | ||
| 445 | if ($res[0] == 'ok'){ | 445 | if ($res[0] == 'ok'){ |
| 446 | - return true; | 446 | + return $folder; |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | throw new \Exception('create folder error:'.end($res[1])); | 449 | throw new \Exception('create folder error:'.end($res[1])); |
| @@ -46,6 +46,20 @@ return [ | @@ -46,6 +46,20 @@ return [ | ||
| 46 | 'mail/folder/create' => [\Controller\Folder::class, 'create'], | 46 | 'mail/folder/create' => [\Controller\Folder::class, 'create'], |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | + * 邮件/重命名文件夹 | ||
| 50 | + * @see \Controller\Folder::rename() | ||
| 51 | + * @param string _token_ token登录凭证 | ||
| 52 | + */ | ||
| 53 | + 'mail/folder/rename' => [\Controller\Folder::class, 'rename'], | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * 邮件/删除文件夹 | ||
| 57 | + * @see \Controller\Folder::delete() | ||
| 58 | + * @param string _token_ token登录凭证 | ||
| 59 | + */ | ||
| 60 | + 'mail/folder/delete' => [\Controller\Folder::class, 'delete'], | ||
| 61 | + | ||
| 62 | + /** | ||
| 49 | * 发送邮件 | 63 | * 发送邮件 |
| 50 | * @see \Controller\Home::send_mail() | 64 | * @see \Controller\Home::send_mail() |
| 51 | * @param string _token_ token登录凭证 | 65 | * @param string _token_ token登录凭证 |
-
请 注册 或 登录 后发表评论