作者 邓超

1

@@ -4,7 +4,21 @@ @@ -4,7 +4,21 @@
4 4
5 //use Model\listsSql; 5 //use Model\listsSql;
6 6
7 -//include_once __DIR__."/../vendor/autoload.php"; 7 +include_once __DIR__."/../vendor/autoload.php";
  8 +
  9 +//$pm = new Swoole\Process\Manager();
  10 +//
  11 +//$pm->add(function (){
  12 +// go(function (){
  13 +// var_dump(co::getCid());
  14 +// co::defer(function (){
  15 +// var_dump(co::getCid());
  16 +// });
  17 +// });
  18 +// co::sleep(9999);
  19 +//},true);
  20 +//
  21 +//$pm->start();
8 // 22 //
9 //print_r(redis()->incr('asdfasdfasdfasdf',600)); 23 //print_r(redis()->incr('asdfasdfasdfasdf',600));
10 24
@@ -18,16 +18,16 @@ function start(){ @@ -18,16 +18,16 @@ function start(){
18 $pm = new Process\Manager(); 18 $pm = new Process\Manager();
19 19
20 // 启动一个进程来管理定时 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 -  
30 - },true); 21 +// $pm->add(function (Process\Pool $pool, int $workerId){
  22 +// _echo("定时进程({$workerId})启动成功");
  23 +//
  24 +//
  25 +// // 进行阻塞,否则定时器无法运行
  26 +// while (true){
  27 +// co::sleep(9999);
  28 +// }
  29 +//
  30 +// },true);
31 31
32 32
33 // 协程配置 33 // 协程配置
@@ -63,7 +63,7 @@ function start(){ @@ -63,7 +63,7 @@ function start(){
63 sync($id,$worker_id); 63 sync($id,$worker_id);
64 }catch (\Throwable $e){ 64 }catch (\Throwable $e){
65 // 重新发布同步任务,如果失败了是否重新发布 65 // 重新发布同步任务,如果失败了是否重新发布
66 - redis()->rPush('sync_email_lists',$id); 66 +// redis()->rPush('sync_email_lists',$id);
67 67
68 // _echo($e->getMessage()); 68 // _echo($e->getMessage());
69 logs( 69 logs(
@@ -101,13 +101,115 @@ function start(){ @@ -101,13 +101,115 @@ function start(){
101 101
102 102
103 },true); 103 },true);
  104 + // 启动一个同步内容的进程
  105 + $pm->add(function (Process\Pool $pool, int $worker_id){
  106 + _echo("业务进程({$worker_id})启动成功,body");
104 107
  108 + $start_num = 0;// 启动的协程数量
  109 +
  110 + // 循环阻塞
  111 + while (true){
  112 + // 是否到了协程配置的数量上限
  113 + if($start_num < 50){
  114 + // 需要同步的id
  115 + $id = redis()->lPop('sync_email_body');
  116 +
  117 + if(!$id){
  118 + co::sleep(1);
  119 + }else{
  120 + // 占用当前的id,占用2小时
  121 + redis()->add('just_sync_body_'.$id['lists_id'],time(),600);
  122 + // 启动一个协程
  123 + go(function () use (&$start_num,$worker_id,$id){
  124 +
  125 + $start_num++;
  126 +
  127 + // 开始同步
  128 + try {
  129 + sync_body($id,$worker_id);
  130 + }catch (\Throwable $e){
  131 +// _echo($e->getMessage());
  132 + logs(
  133 + $e->getMessage().PHP_EOL.$e->getTraceAsString(),
  134 + LOG_PATH.'/'.$worker_id.'_'.co::getCid().'.log'
  135 + );
  136 + }
  137 +
  138 + // 协程完成后执行的函数
  139 + co::defer(function () use (&$start_num,$worker_id,$id){
  140 +// _echo('正常关闭进程('.$worker_id.')下的协程('.co::getCid().')');
  141 + $start_num--;
  142 + // 消除占用
  143 + redis()->delete('just_sync_body_'.$id['lists_id']);
  144 + // 写入日志
  145 + \Lib\Log::getInstance()->write();
  146 +
  147 + // 关闭数据库链接
  148 + db()->close();
  149 + // 关闭redis链接
  150 + redis()->close();
  151 +
  152 + });
  153 +
  154 + });
  155 +
  156 + }
  157 + }else{
  158 + // 协程到了最大的数量,阻塞1秒
  159 + co::sleep(1);
  160 + }
  161 +
  162 +
  163 + }
  164 +
  165 +
  166 + },true);
105 167
106 // 启动管理器 168 // 启动管理器
107 $pm->start(); 169 $pm->start();
108 170
109 } 171 }
110 172
  173 +/**
  174 + * 同步内容 body
  175 + * @param $id
  176 + * @param $worker_id
  177 + * @return int
  178 + * @author:dc
  179 + * @time 2023/3/23 10:18
  180 + */
  181 +function sync_body($id,$worker_id){
  182 +
  183 + // 是否有数据
  184 + if(db()->count(\Model\bodySql::has((int) $id['lists_id']))){
  185 + return 0;
  186 + }
  187 +
  188 + $email = db()->first(\Model\emailSql::first($id['email_id']));
  189 + if(!$email){
  190 + return 0;
  191 + }
  192 +
  193 + if($email['pwd_error']){
  194 + return 1;
  195 + }
  196 +
  197 + $mailServer = new Lib\Mail\Mail($email['email'],base64_decode($email['password']),$email['imap']);
  198 +
  199 + // 登录服务器
  200 + if(!$mailServer->login()){
  201 + return 2;
  202 + }
  203 +
  204 + // 同步 body
  205 + $mailServer->syncBody($id['folder'],$id['uid'],$id['lists_id'],db());
  206 +
  207 + $mailServer = null;
  208 +
  209 + return 0;
  210 +
  211 +}
  212 +
111 213
112 /** 214 /**
113 * 开始同步, 这里是主要的业务代码 215 * 开始同步, 这里是主要的业务代码
@@ -18,6 +18,8 @@ define('APP_LANG','zh'); @@ -18,6 +18,8 @@ define('APP_LANG','zh');
18 18
19 // 根目录 19 // 根目录
20 define('ROOT_PATH',__DIR__); 20 define('ROOT_PATH',__DIR__);
  21 +// 对外的web目录
  22 +define('PUBLIC_PATH',ROOT_PATH.'/public');
21 23
22 24
23 // redis 25 // redis
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 namespace Lib\Mail; 3 namespace Lib\Mail;
4 4
5 use Lib\DbPool; 5 use Lib\DbPool;
  6 +use Model\bodySql;
6 use Model\folderSql; 7 use Model\folderSql;
7 use Model\listsSql; 8 use Model\listsSql;
8 9
@@ -254,7 +255,15 @@ class Mail { @@ -254,7 +255,15 @@ class Mail {
254 foreach ($results as $insert){ 255 foreach ($results as $insert){
255 if(empty($uuids[$insert['uuid']])){ 256 if(empty($uuids[$insert['uuid']])){
256 // 新增 257 // 新增
257 - $db->insert(listsSql::$table,$insert); 258 + $id = $db->insert(listsSql::$table,$insert);
  259 + // 同步body内容
  260 + redis()->rPush('sync_email_body', [
  261 + 'lists_id' => $id,
  262 + 'email_id' => $email_id,
  263 + 'folder_id' => $folder_id,
  264 + 'folder' => $folder,
  265 + 'uid' => $insert['uid'],
  266 + ]);
258 }else{ 267 }else{
259 // 修改 268 // 修改
260 $db->update( 269 $db->update(
@@ -296,15 +305,22 @@ class Mail { @@ -296,15 +305,22 @@ class Mail {
296 * @author:dc 305 * @author:dc
297 * @time 2023/2/9 10:29 306 * @time 2023/2/9 10:29
298 */ 307 */
299 - public static function syncBody($id,$msgno, $email_id,$folder_name,$email):bool { 308 + public function syncBody($folder_name, $uid ,$id,$db=null):bool {
300 309
  310 + $db = $db ? $db : db();
301 // 选择文件夹 311 // 选择文件夹
302 - static::$client[$email]->selectFolder($folder_name); 312 + $this->client->selectFolder($folder_name);
  313 +
  314 + $body = $this->client->fetchBody([$uid],PUBLIC_PATH.'/attachment/',true);
303 315
304 - $body = static::$client[$email]->fetchBody([$msgno],storage_path('email/'.$email_id)); 316 + $body = array_values($body);
  317 + $body = $body[0]['RFC822.TEXT']??'';
305 318
306 - if(!empty($body[$msgno]['RFC822.TEXT'])){  
307 - \App\Models\Body::_insert($id,$body[$msgno]['RFC822.TEXT']); 319 + if(!empty($body)){
  320 + $db->insert(bodySql::$table,[
  321 + 'lists_id' => $id,
  322 + 'body' => $body
  323 + ]);
308 } 324 }
309 325
310 return true; 326 return true;
  1 +<?php
  2 +
  3 +namespace Model;
  4 +
  5 +/**
  6 + * body
  7 + * @author:dc
  8 + * @time 2023/3/23 10:13
  9 + * Class bodySql
  10 + * @package Model
  11 + */
  12 +class bodySql {
  13 +
  14 + public static $table = 'bodies';
  15 +
  16 +
  17 + /**
  18 + *
  19 + * @param int $id
  20 + * @return string
  21 + * @author:dc
  22 + * @time 2023/3/23 10:15
  23 + */
  24 + public static function first(int $id):string {
  25 + return "select * from `".static::$table."` where `id` = {$id} limit 1";
  26 + }
  27 +
  28 + /**
  29 + * has
  30 + * @param int $id
  31 + * @return string
  32 + * @author:dc
  33 + * @time 2023/3/23 10:15
  34 + */
  35 + public static function has(int $id){
  36 + return "select count(*) from `".static::$table."` where `id` = {$id} limit 1";
  37 + }
  38 +
  39 +
  40 +
  41 +}