<?php namespace Service; use Lib\Mail\MailFun; use Model\emailSql; use Model\listsSql; /** * @author:dc * @time 2025/3/11 9:20 * Class MailProxy * @package Service */ class MailProxy { /** 原域名 * @var */ protected $originImapHost = ''; protected $originSmtpHost = ''; /** * 代理服务器 * @var string */ private $proxyImapHost = ''; private $proxySmtpHost = ''; /** * 代理配置 * @var array */ protected $config = [ 'smtp.gmail.com:465' => '10087', 'imap.gmail.com:993' => '10086', 'imap-mail.outlook.com:993' => '10088', 'smtp-mail.outlook.com:465' => '10089', 'imap.mail.yahoo.com:993' => '10092', 'smtp.mail.yahoo.com:465' => '10093', 'imaphz.qiye.163.com:993' => '10080', 'smtphz.qiye.163.com:465' => '10081', 'imap.qiye.aliyun.com:993' => '10094', 'smtp.qiye.aliyun.com:465' => '10095', // 'imap.qq.com:993' => '10096', // 'smtp.qq.com:465' => '10097', ]; /** * 代理服务器 地址 * @var string[] */ protected $proxyService = [ '43.134.162.250', // 这个是新加坡服务器 代理 '119.28.113.113', // 这个是新加坡服务器 代理02 '43.154.117.107', // 这个是 shopk的那台服务器 ]; /** * 分配到的ip服务 * @var string */ protected $assignIp = ''; /** * 邮箱 * @var string */ protected $email = ''; protected $defaultIp = ''; /** * MailProxy constructor. * @param string $email * @param string $imap * @param string $smtp * @param string $default * @throws \Exception */ public function __construct(string $email, string $imap, string $smtp,string $default='') { $this->email = str_replace(['"',"'"],'',$email); if($default){ $this->defaultIp = $default; } // 先分配 $this->assignEmail(); $this->originImapHost = $imap; $this->originSmtpHost = $smtp; // 不需要分配 if($this->assignIp===false){ // 解析 $this->proxyImapHost = $imap; // 解析 $this->proxySmtpHost = $smtp; }else{ // 解析 $this->proxyImapHost = $this->parse($imap,993); // 解析 $this->proxySmtpHost = $this->parse($smtp,465); } } /** * 代理地址 * @author:dc * @time 2025/3/13 17:38 */ public function getImapProxy(){ return $this->proxyImapHost; } /** * 代理地址 * @return string * @author:dc * @time 2025/3/14 10:31 */ public function getSmtpProxy(){ return $this->proxySmtpHost; } /** * @return mixed */ public function getOriginImapHost(): string { return $this->originImapHost; } /** * @return string */ public function getOriginSmtpHost(): string { return $this->originSmtpHost; } /** * 解析地址 * @param string $host * @param int $port * @return string * @author:dc * @time 2025/3/13 17:18 */ public function parse(string $host, int $port){ $host = parse_url($host); // 协议 $scheme = $host['scheme']??'ssl'; // 地址 $serve = strtolower(empty($host['host']) ? $host['path'] : $host['host']); // 传入的是代理地址 并且是数据库里面已分配的ip if(in_array($serve,$this->proxyService)){ // 传入的服务器 和 分配的不一致 更新分配的 if($serve != $this->assignIp){ $this->assignIp = $serve; // 更新 ip $this->updateIp(); } }else{ // 端口 $port = (empty($host['port'])?$port:$host['port']); // 端口不在,说明没有配置 if(empty($this->config[$serve.':'.$port])){ // 返回不代理 $this->assignIp = $serve; }else{ if(in_array($this->assignIp,$this->proxyService)){ $port = $this->config[$serve.':'.$port]; // 代理服务器端口 } } } // 组装 $proxyHost = $scheme.'://'.$this->assignIp.":".(empty($host['port'])?$port:$host['port']); return implode(':',MailFun::getHostPort($proxyHost)); } /** * 分配邮箱 到 服务器 * @author:dc * @time 2025/3/11 18:01 */ private function assignEmail(){ $data = db()->throw()->first('select * from mail_proxy where email = "'.$this->email.'"'); // 存在记录 并且 还在服务器列表 if($data && in_array($data['ip'],$this->proxyService)){ $this->assignIp = $data['ip']; return ; } if(!$data){ // 如果 已经有之前的邮箱了, 就不进行代理了 if(db()->count(emailSql::first($this->email))){ $this->assignIp = false; return ; } } // 默认指定 ip if($this->defaultIp){ $this->assignIp = $this->defaultIp; if($data){ if($data['ip'] == $this->defaultIp){ return ; }else{ $this->updateIp(); } }else{ $this->createIp(); } return ; } // 一个月活跃用户 $t = date('Y-m-d H:i:s',strtotime("-30 day")); foreach ($this->proxyService as $ip){ // shopk的不分配 if($ip=='43.154.117.107'){ continue; } $num = db()->count("select count(*) from `mail_proxy` where `status` = 1 and `time` > '{$t}' and `ip` = '{$ip}'"); // 每个ip分配1000个 if($num<1000){ $this->assignIp = $ip; // 如果某个服务器 停止了,进来了就要重新分配 if($data){ $this->updateIp(); }else{ $this->createIp(); } return ; } } throw new \Exception('没有资源可分配'); } /** * 更新ip * @param $ip * @author:dc * @time 2025/3/14 15:55 */ protected function updateIp(){ db()->throw()->update('mail_proxy',[ 'ip' => $this->assignIp, 'time' => date('Y-m-d H:i:s'), ],dbWhere(['email'=>$this->email]),false); } /** * 创建 * @author:dc * @time 2025/3/14 15:57 */ protected function createIp(){ db()->throw()->insert('mail_proxy',[ 'email' => $this->email, 'ip' => $this->assignIp, 'time' => date('Y-m-d H:i:s'), 'status' => 0 ],false); } /** * 标记为正常使用代理 * @author:dc * @time 2025/3/14 14:39 */ public function proxySuccess(){ db()->update('mail_proxy',[ 'status' => 1, 'time' => date('Y-m-d H:i:s'), ],dbWhere(['email'=>$this->email]),false); } }