作者 邓超

1

1 <?php 1 <?php
2 2
3 -#echo file_get_contents('http://gold.cnfol.com/mingjiadianjin/20230210/30052311.shtml');  
  3 +include_once __DIR__."/../vendor/autoload.php";
  4 +
  5 +
  6 +$ids = db()->all('select `id` from `'.\Model\emailSql::$table.'` limit 1000 offset 0');
  7 +print_r($ids);
@@ -27,7 +27,7 @@ function start(){ @@ -27,7 +27,7 @@ function start(){
27 27
28 // 启动一个进程来管理定时 28 // 启动一个进程来管理定时
29 $pm->add(function (Process\Pool $pool, int $workerId)use (&$table){ 29 $pm->add(function (Process\Pool $pool, int $workerId)use (&$table){
30 - _echo("进程({$workerId})启动成功"); 30 + _echo("定时进程({$workerId})启动成功");
31 // 每10分钟统计一次邮箱数量 31 // 每10分钟统计一次邮箱数量
32 \Swoole\Timer::tick(600000,function () use (&$table){ 32 \Swoole\Timer::tick(600000,function () use (&$table){
33 $table->set('etotal',['val'=> db()->count(\Model\emailSql::count())]); 33 $table->set('etotal',['val'=> db()->count(\Model\emailSql::count())]);
@@ -60,6 +60,27 @@ function start(){ @@ -60,6 +60,27 @@ function start(){
60 60
61 }); 61 });
62 62
  63 +
  64 + // 需要更新同步的邮件
  65 + \Swoole\Timer::tick(600000,function (){
  66 +
  67 + $id = 0;
  68 +
  69 + while (true){
  70 + $ids = db()->all('select `id` from `'.\Model\emailSql::$table.'` where `id` > '.$id.' order by `id` asc limit 1000 offset 0');
  71 + if(!$ids){
  72 + break;
  73 + }
  74 + foreach ($ids as $v){
  75 + $id = $v['id'];
  76 + redis()->rPush('sync_email_lists', $v['id']);
  77 + }
  78 + }
  79 +
  80 + });
  81 +
  82 +
  83 +
63 // 进行阻塞,否则定时器无法运行 84 // 进行阻塞,否则定时器无法运行
64 while (true){ 85 while (true){
65 co::sleep(9999); 86 co::sleep(9999);
@@ -75,7 +96,7 @@ function start(){ @@ -75,7 +96,7 @@ function start(){
75 96
76 // 启动业务进程 97 // 启动业务进程
77 $pm->addBatch(WORKER_NUM,function (Process\Pool $pool, int $worker_id) use (&$table){ 98 $pm->addBatch(WORKER_NUM,function (Process\Pool $pool, int $worker_id) use (&$table){
78 - _echo("进程({$worker_id})启动成功"); 99 + _echo("业务进程({$worker_id})启动成功");
79 100
80 // 协程id集 101 // 协程id集
81 $cid = []; 102 $cid = [];
@@ -147,6 +168,7 @@ function start(){ @@ -147,6 +168,7 @@ function start(){
147 },true); 168 },true);
148 169
149 170
  171 + // 启动管理器
150 $pm->start(); 172 $pm->start();
151 173
152 } 174 }
@@ -195,12 +217,50 @@ function create_coroutine(array &$cid,int &$isRunMaxCNum,$worker_id){ @@ -195,12 +217,50 @@ function create_coroutine(array &$cid,int &$isRunMaxCNum,$worker_id){
195 217
196 218
197 /** 219 /**
198 - * 开始同步 220 + * 开始同步, 这里是主要的业务代码
199 * @author:dc 221 * @author:dc
200 * @time 2023/2/13 9:42 222 * @time 2023/2/13 9:42
201 */ 223 */
202 function sync(){ 224 function sync(){
203 - co::sleep(1); 225 + // 需要同步的id
  226 + $id = redis()->lPop('sync_email_lists');
  227 + if(!$id){
  228 + co::sleep(1);
  229 + return -1;
  230 + }
  231 +
  232 + $email = db()->first(\Model\emailSql::first($id));
  233 + if(!$email){
  234 + return 0;
  235 + }
  236 +
  237 + if($email['pwd_error']){
  238 + return 1;
  239 + }
  240 +
  241 + $mailServer = new Lib\Mail\Mail();
  242 +
  243 + try {
  244 + // 登录服务器
  245 + $mailServer->login($email['email'],base64_decode($email['password']),$email['imap']);
  246 + }catch (Throwable $e){
  247 + if($e->getCode() == 403){
  248 + // 登录失败了 ,
  249 + db()->update(\Model\emailSql::$table,['pwd_error'=>1],dbWhere(['id'=>$id]));
  250 + }
  251 +
  252 + return 2;
  253 + }
  254 +
  255 + $mailServer->client->setId($id);
  256 + // 同步文件夹
  257 + $mailServer->syncFolder($email['email'],db());
  258 +
  259 +
  260 +
  261 + $email = null;
  262 + $mailServer = null;
  263 +
204 } 264 }
205 265
206 266
@@ -63,6 +63,14 @@ class Home { @@ -63,6 +63,14 @@ class Home {
63 }else{ 63 }else{
64 // 新增 64 // 新增
65 $ret = db()->insert(emailSql::$table,$data); 65 $ret = db()->insert(emailSql::$table,$data);
  66 +
  67 + if($ret){
  68 + // 增加邮件数量
  69 + redis()->incr('email_total');
  70 + // 立即处理 同步
  71 + redis()->lPush('sync_email_lists', $ret);
  72 + }
  73 +
66 } 74 }
67 75
68 76
@@ -192,7 +192,7 @@ class Imap { @@ -192,7 +192,7 @@ class Imap {
192 192
193 //解析登录数据每个服务商返回的登录结果不一样,很难兼容 193 //解析登录数据每个服务商返回的登录结果不一样,很难兼容
194 if($result[0] != 'ok'){ 194 if($result[0] != 'ok'){
195 - throw new \Exception('IMAP Login Error:'.end($result[1])); 195 + throw new \Exception('IMAP Login Error:'.end($result[1]),403);
196 } 196 }
197 197
198 // 是否是只读模式 198 // 是否是只读模式
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 namespace Lib\Mail; 3 namespace Lib\Mail;
4 4
  5 +use Lib\DbPool;
  6 +
5 /** 7 /**
6 * 操作邮件 8 * 操作邮件
7 * @author:dc 9 * @author:dc
@@ -13,9 +15,9 @@ class Mail { @@ -13,9 +15,9 @@ class Mail {
13 15
14 /** 16 /**
15 * imap服务器连接实例 17 * imap服务器连接实例
16 - * @var Imap[] 18 + * @var Imap
17 */ 19 */
18 - public static array $client = []; 20 + public Imap $client;
19 21
20 22
21 /** 23 /**
@@ -26,36 +28,31 @@ class Mail { @@ -26,36 +28,31 @@ class Mail {
26 * @author:dc 28 * @author:dc
27 * @time 2023/2/5 10:46 29 * @time 2023/2/5 10:46
28 */ 30 */
29 - public static function login(string $email,string $password,string $imap) {  
30 - if(!empty(static::$client[$email]) && static::$client[$email] instanceof Imap){  
31 - if(static::$client[$email]->noop()){  
32 - return true;  
33 - }  
34 - }  
35 - static::$client[$email] = new Imap();  
36 -// $imap->debug(); 31 + public function login(string $email,string $password,string $imap) {
  32 +
  33 + $this->client = new Imap();
  34 +
37 // 是否初始成功 35 // 是否初始成功
38 - static::$client[$email]->login("ssl://{$imap}:993",$email,$password); 36 + $this->client->login("ssl://{$imap}:993",$email,$password);
  37 +
39 return true; 38 return true;
40 } 39 }
41 40
42 41
43 /** 42 /**
44 * 同步文件夹 43 * 同步文件夹
45 - * @param $email  
46 - * @param MySQL|null $db 44 + * @param DbPool|null $db
47 * @return mixed 45 * @return mixed
48 * @author:dc 46 * @author:dc
49 * @time 2023/2/5 10:58 47 * @time 2023/2/5 10:58
50 */ 48 */
51 - public static function syncFolder($email,$db=null){  
52 - 49 + public function syncFolder($db=null){
  50 + $db = $db ? $db : db();
53 // 读取所有文件夹,未解密 51 // 读取所有文件夹,未解密
54 - $folders = static::$client[$email]->getFolder(); 52 + $folders = $this->client->getFolder();
55 53
56 - DB::beginTransaction(); 54 + $db->transaction();
57 foreach ($folders as $folder){ 55 foreach ($folders as $folder){
58 -  
59 // 处理子父文件夹 56 // 处理子父文件夹
60 $folder['id'] = explode('/',$folder['folder']); 57 $folder['id'] = explode('/',$folder['folder']);
61 $folder['name'] = explode('/',$folder['parseFolder']); 58 $folder['name'] = explode('/',$folder['parseFolder']);
@@ -63,14 +60,14 @@ class Mail { @@ -63,14 +60,14 @@ class Mail {
63 foreach ($folder['id'] as $k=>$item){ 60 foreach ($folder['id'] as $k=>$item){
64 // 插入到数据库 61 // 插入到数据库
65 $pid = Folder::_insert( 62 $pid = Folder::_insert(
66 - static::$client[$email]->getId(), 63 + $this->client->getId(),
67 $folder['name'][$k], 64 $folder['name'][$k],
68 $item, 65 $item,
69 $pid 66 $pid
70 ); 67 );
71 } 68 }
72 } 69 }
73 - DB::commit(); 70 + $db->commit();
74 71
75 } 72 }
76 73
@@ -135,6 +135,28 @@ class RedisPool { @@ -135,6 +135,28 @@ class RedisPool {
135 return $this->unserialize($this->client->rPop($key)); 135 return $this->unserialize($this->client->rPop($key));
136 } 136 }
137 137
  138 + /**
  139 + * 自增
  140 + * @param $key
  141 + * @return int
  142 + * @author:dc
  143 + * @time 2023/2/17 15:29
  144 + */
  145 + public function incr($key){
  146 + return $this->client->incr($key);
  147 + }
  148 +
  149 + /**
  150 + * 自减
  151 + * @param $key
  152 + * @return int
  153 + * @author:dc
  154 + * @time 2023/2/17 15:29
  155 + */
  156 + public function decr($key){
  157 + return $this->client->decr($key);
  158 + }
  159 +
138 160
139 /** 161 /**
140 * 删除 162 * 删除
  1 +<?php
  2 +
  3 +namespace Model;
  4 +
  5 +/**
  6 + * 文件夹
  7 + * @author:dc
  8 + * @time 2023/2/17 18:04
  9 + * Class folderSql
  10 + * @package Model
  11 + */
  12 +class folderSql {
  13 +
  14 + public static $table = 'folders';
  15 +
  16 +
  17 +
  18 +
  19 +
  20 +
  21 +
  22 +}
@@ -32,7 +32,7 @@ class listsSql { @@ -32,7 +32,7 @@ class listsSql {
32 $where = ['email_id'=>$email_id]; 32 $where = ['email_id'=>$email_id];
33 if($folder_id) $where['folder_id'] = $folder_id; 33 if($folder_id) $where['folder_id'] = $folder_id;
34 34
35 - return "select * from `".static::$table."` where ".dbWhere($where)." order by `udate` desc limit 30 offset ".($p-1); 35 + return "select * from `".static::$table."` where ".dbWhere($where)." order by `udate` desc limit 30 offset ".(($p-1)*30);
36 36
37 } 37 }
38 38