正在显示
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登录凭证 |
-
请 注册 或 登录 后发表评论