作者 邓超

x

@@ -15,7 +15,7 @@ function start(){ @@ -15,7 +15,7 @@ function start(){
15 $pm = new Process\Manager(); 15 $pm = new Process\Manager();
16 16
17 // 启动业务进程 17 // 启动业务进程
18 - $pm->addBatch(10,function (Process\Pool $pool, int $worker_id){ 18 + $pm->addBatch(15,function (Process\Pool $pool, int $worker_id){
19 19
20 swoole_set_process_name('php-email-sync-list-'.$worker_id); 20 swoole_set_process_name('php-email-sync-list-'.$worker_id);
21 21
@@ -41,19 +41,12 @@ function start(){ @@ -41,19 +41,12 @@ function start(){
41 go(function () use ($id){ 41 go(function () use ($id){
42 42
43 // 开始同步 43 // 开始同步
44 - try {  
45 - sync($id);  
46 - }catch (\Throwable $e){  
47 - logs(  
48 - $e->getMessage().PHP_EOL.$e->getTraceAsString(),  
49 - LOG_PATH.'/sync/'.$id.'.log'  
50 - );  
51 - } 44 + (new \Service\SyncMail($id))->sync();
52 45
53 // 协程完成后执行的函数 46 // 协程完成后执行的函数
54 co::defer(function () use ($id){ 47 co::defer(function () use ($id){
55 // 30秒后 消除占用 48 // 30秒后 消除占用
56 - redis()->expire('just_sync_'.$id,30); 49 + redis()->expire('just_sync_'.$id,60);
57 // 写入日志 50 // 写入日志
58 \Lib\Log::getInstance()->write(); 51 \Lib\Log::getInstance()->write();
59 }); 52 });
@@ -69,190 +62,12 @@ function start(){ @@ -69,190 +62,12 @@ function start(){
69 62
70 },true); 63 },true);
71 64
72 - // 启动一个同步内容的进程  
73 -// $pm->add(function (Process\Pool $pool, int $worker_id){  
74 -//  
75 -// swoole_set_process_name('php-email-sync-body-'.$worker_id);  
76 -//  
77 -// include_once __DIR__."/../vendor/autoload.php";  
78 -//  
79 -// _echo("业务进程({$worker_id})启动成功,body");  
80 -// $run_timer = time();  
81 -// // 循环阻塞  
82 -// while (true){  
83 -// // 运行超过1天的 停止  
84 -// if($run_timer < (time()-21600)){  
85 -// break;  
86 -// }  
87 -// // 需要同步的id  
88 -// $id = redis()->lPop('sync_email_body');  
89 -//  
90 -// if(!$id){  
91 -// co::sleep(1);  
92 -// }else{  
93 -// // 占用当前的id,占用2小时  
94 -// if(redis()->add('just_sync_body_'.$id['lists_id'],time(),600)){  
95 -// // 启动一个协程  
96 -// go(function () use ($id){  
97 -//  
98 -// // 开始同步  
99 -// try {  
100 -// sync_body($id);  
101 -// }catch (\Throwable $e){  
102 -//// _echo($e->getMessage());  
103 -// logs(  
104 -// $e->getMessage().PHP_EOL.$e->getTraceAsString(),  
105 -// LOG_PATH.'/'.$id['email_id'].'.log'  
106 -// );  
107 -// }  
108 -//  
109 -// // 协程完成后执行的函数  
110 -// co::defer(function () use ($id){  
111 -//// _echo('正常关闭进程('.$worker_id.')下的协程('.co::getCid().')');  
112 -// // 消除占用  
113 -// redis()->delete('just_sync_body_'.$id['lists_id']);  
114 -// // 写入日志  
115 -// \Lib\Log::getInstance()->write();  
116 -//  
117 -// });  
118 -//  
119 -// });  
120 -// }  
121 -// }  
122 -//  
123 -// }  
124 -//  
125 -// },true);  
126 65
127 // 启动管理器 66 // 启动管理器
128 $pm->start(); 67 $pm->start();
129 68
130 } 69 }
131 70
132 -/**  
133 - * 同步内容 body  
134 - * @param $id  
135 - * @param $worker_id  
136 - * @return int  
137 - * @author:dc  
138 - * @time 2023/3/23 10:18  
139 - */  
140 -function sync_body($id){  
141 -  
142 - // 是否有数据  
143 - if(db()->count(\Model\bodySql::has((int) $id['lists_id']))){  
144 - return 0;  
145 - }  
146 -  
147 - $email = db()->first(\Model\emailSql::first($id['email_id']));  
148 - if(!$email){  
149 - return 0;  
150 - }  
151 -  
152 - if($email['pwd_error']){  
153 - return 1;  
154 - }  
155 -  
156 - $mailServer = new Lib\Mail\Mail($email['email'],base64_decode($email['password']),$email['imap']);  
157 -  
158 - // 登录服务器  
159 - if($mailServer->login()!=1){  
160 - return 2;  
161 - }  
162 -// $mailServer->client->debug(true,LOG_PATH.'/'.$id['email_id'].'body/');  
163 -  
164 - // 同步 body  
165 - $mailServer->syncBody($id['folder'],$id['uid'],$id['lists_id'],db());  
166 -  
167 - $mailServer = null;  
168 -  
169 - return 0;  
170 -  
171 -}  
172 -  
173 -  
174 -/**  
175 - * 开始同步, 这里是主要的业务代码  
176 - * @param $email_id  
177 - * @param $worker_id  
178 - * @return int  
179 - * @author:dc  
180 - * @time 2023/3/10 10:19  
181 - */  
182 -function sync($email_id){  
183 -  
184 - $email = db()->first(\Model\emailSql::first($email_id));  
185 - if(!$email){  
186 - return 0;  
187 - }  
188 -  
189 - if($email['pwd_error']){  
190 - return 1;  
191 - }  
192 -  
193 - $mailServer = new Lib\Mail\Mail($email['email'],base64_decode($email['password']),$email['imap']);  
194 -  
195 - // 登录服务器  
196 - if($mailServer->login()!==1){  
197 - return 2;  
198 - }  
199 -  
200 -// $mailServer->client->debug(true,LOG_PATH.'/'.$email_id.'/');  
201 -  
202 - // 同步文件夹  
203 - $mailServer->syncFolder($email_id);  
204 - _echo('文件夹同步成功-'.$email_id);  
205 -  
206 - // 读取到邮箱中的文件夹  
207 - $folders = db()->all(\Model\folderSql::all($email['id']));  
208 - if(!$folders){  
209 - return 3;  
210 - }  
211 -  
212 - $call = function ($email_id,$folder_id,$origin_folder) use ($mailServer){  
213 - // gmail 邮箱 这个是不可选的  
214 - if($origin_folder == '[Gmail]'){  
215 - return;  
216 - }  
217 - // 同步父文件夹  
218 - $result = $mailServer->syncMail($email_id,$folder_id,$origin_folder);  
219 - if(is_array($result) && $result){  
220 - _echo($email_id.' 同步文件夹('.$origin_folder.')邮件列表 '.count($result));  
221 - }  
222 -  
223 - };  
224 -  
225 -// $folders = list_to_tree($folders);  
226 - foreach ($folders as $folder){  
227 - try {  
228 - $is = true;  
229 - foreach ($folders as $f){  
230 - // 是否存在下级  
231 - if($f['pid'] == $folder['id']){  
232 - $is = false;  
233 - }  
234 - }  
235 -  
236 - if($is) $call($email_id,$folder['id'],$folder['origin_folder']);  
237 -  
238 - }catch (\Throwable $e){  
239 - logs(  
240 - $e->getMessage().$e->getTraceAsString(),  
241 - LOG_PATH.'/imap/'.$email['email'].'.error.log'  
242 - );  
243 - }  
244 - }  
245 -  
246 -  
247 - $email = null;  
248 - $mailServer = null;  
249 -}  
250 -  
251 -  
252 -if(!function_exists("imap_8bit")){  
253 - echo '请安装imap扩展';  
254 - exit(0);  
255 -}  
256 71
257 72
258 73
@@ -174,23 +174,53 @@ class SyncMail { @@ -174,23 +174,53 @@ class SyncMail {
174 if($f->isSelect){ // 是否可以选择 只有可以选中的文件夹才有邮件 174 if($f->isSelect){ // 是否可以选择 只有可以选中的文件夹才有邮件
175 $folder = $this->imap->folder($f); // 选择文件夹后,有状态 175 $folder = $this->imap->folder($f); // 选择文件夹后,有状态
176 176
177 - // 这个暂时不要  
178 -// $this->db->update(folderSql::$table,[  
179 -// 'exsts' => $folder->getTotal(),  
180 -// 'unseen' => $folder->getUnseen(),  
181 -// 'last_sync_time' => time()  
182 -// ],dbWhere(['email_id'=>$this->emailId(),'origin_folder'=>$folder->getName()]),false);  
183 -  
184 // 是否有邮件 有邮件才继续 177 // 是否有邮件 有邮件才继续
185 if ($folder->getTotal()){ 178 if ($folder->getTotal()){
186 $this->mail($folder); 179 $this->mail($folder);
187 } 180 }
  181 +
  182 + // 更新数量
  183 + $this->db->update(folderSql::$table,[
  184 + 'exsts' => $this->db->count(listsSql::listCount(
  185 + dbWhere(
  186 + [
  187 + 'folder_id'=>$this->getFolderId($folder->getName()),
  188 + 'deleted' => 0,
  189 + ]
  190 + )
  191 + )),
  192 + 'unseen' => $this->db->count(listsSql::listCount(
  193 + dbWhere(
  194 + [
  195 + 'folder_id'=>$this->getFolderId($folder->getName()),
  196 + 'seen' => 0,
  197 + 'deleted' => 0,
  198 + ]
  199 + )
  200 + )),
  201 + 'last_sync_time' => time()
  202 + ],dbWhere(['email_id'=>$this->emailId(),'uuid'=>md5($this->emailId().$folder->getName())]),false);
  203 +
188 } 204 }
189 } 205 }
190 206
191 207
192 } 208 }
193 209
  210 + /**
  211 + * 当前 目录的id
  212 + * @param string $name
  213 + * @return mixed|null
  214 + * @author:dc
  215 + * @time 2024/10/12 17:44
  216 + */
  217 + private function getFolderId(string $name){
  218 + return $this->db->cache(120)->value(folderSql::first([
  219 + 'email_id'=>$this->emailId(),
  220 + 'uuid' => md5($this->emailId().$name)
  221 + ],'`id`'));
  222 + }
  223 +
194 /**同步邮件 224 /**同步邮件
195 * 225 *
196 * @param string|\Lib\Imap\Request\Folder $folder 226 * @param string|\Lib\Imap\Request\Folder $folder
@@ -204,10 +234,7 @@ class SyncMail { @@ -204,10 +234,7 @@ class SyncMail {
204 $folder = $this->imap->folder($folder)->exec(); 234 $folder = $this->imap->folder($folder)->exec();
205 } 235 }
206 236
207 - $folder_id = $this->db->value(folderSql::first([  
208 - 'email_id'=>$this->emailId(),  
209 - 'uuid' => md5($this->emailId().$folder->getName())  
210 - ],'`id`')); 237 + $folder_id = $this->getFolderId($folder->getName());
211 238
212 // 选择成功 239 // 选择成功
213 if($folder->isOk()){ 240 if($folder->isOk()){