PHP 进行统一邮箱登陆的代理实现(swoole),
程序员文章站
2024-01-07 17:40:16
...
PHP 进行统一邮箱登陆的代理实现(swoole),
在工作的过程中,经常会有很多应用有发邮件的需求,这个时候需要在每个应用中配置smtp服务器。一旦公司调整了smtp服务器的配置,比如修改了密码等,这个时候对于维护的人员来说要逐一修改应用中smtp的配置。这样的情况虽然不多见,但遇上了还是很头痛的一件事情。
知道了问题,解决起来就有了方向。于是就有了自己开发一个简单的smtp代理的想法,这个代理主要的功能(参照问题)主要是:
1.接受指定IP应用的smtp请求;
2.应用不需要知道smtp的用户和密码;
3.转发应用的smtp请求。
开发的环境:Linux,php(swoole);
代码如下:
php /** * * SMTP Proxy Server * @author Terry Zhang, 2015-11-13 * * @version 1.0 * * 注意:本程序只能运行在cli模式,且需要扩展Swoole 1.7.20+的支持。 * * Swoole的源代码及安装请参考 https://github.com/swoole/swoole-src/ * * 本程序的使用场景: * * 在多个分散的系统中使用同一的邮件地址进行系统邮件发送时,一旦邮箱密码修改,则要修改每个系统的邮件配置参数。 * 同时,在每个系统中配置邮箱参数,使得邮箱的密码容易外泄。 * * 通过本代理进行邮件发送的客户端,可以随便指定用户名和密码。 * * */ //error_reporting(0); defined('DEBUG_ON') or define('DEBUG_ON', false); //主目录 defined('BASE_PATH') or define('BASE_PATH', __DIR__); class CSmtpProxy{ //软件版本 const VERSION = '1.0'; const EOF = "\r\n"; public static $software = "SMTP-Proxy-Server"; private static $server_mode = SWOOLE_PROCESS; private static $pid_file; private static $log_file; private $smtp_host = 'localhost'; private $smtp_port = 25; private $smtp_user = ''; private $smtp_pass = ''; private $smtp_from = ''; //待写入文件的日志队列(缓冲区) private $queue = array(); public $host = '0.0.0.0'; public $port = 25; public $setting = array(); //最大连接数 public $max_connection = 50; /** * @var swoole_server */ protected $server; protected $connection = array(); public static function setPidFile($pid_file){ self::$pid_file = $pid_file; } public static function start($startFunc){ if(!extension_loaded('swoole')){ exit("Require extension `swoole`.\n"); } $pid_file = self::$pid_file; $server_pid = 0; if(is_file($pid_file)){ $server_pid = file_get_contents($pid_file); } global $argv; if(empty($argv[1])){ goto usage; }elseif($argv[1] == 'reload'){ if (empty($server_pid)){ exit("SMTP Proxy Server is not running\n"); } posix_kill($server_pid, SIGUSR1); exit; }elseif ($argv[1] == 'stop'){ if (empty($server_pid)){ exit("SMTP Proxy is not running\n"); } posix_kill($server_pid, SIGTERM); exit; }elseif ($argv[1] == 'start'){ //已存在ServerPID,并且进程存在 if (!empty($server_pid) and posix_kill($server_pid,(int) 0)){ exit("SMTP Proxy is already running.\n"); } //启动服务器 $startFunc(); }else{ usage: exit("Usage: php {$argv[0]} start|stop|reload\n"); } } public function __construct($host,$port){ $flag = SWOOLE_SOCK_TCP; $this->server = new swoole_server($host,$port,self::$server_mode,$flag); $this->host = $host; $this->port = $port; $this->setting = array( 'backlog' => 128, 'dispatch_mode' => 2, ); } public function daemonize(){ $this->setting['daemonize'] = 1; } public function getConnectionInfo($fd){ return $this->server->connection_info($fd); } /** * 启动服务进程 * @param array $setting * @throws Exception */ public function run($setting = array()){ $this->setting = array_merge($this->setting,$setting); //不使用swoole的默认日志 if(isset($this->setting['log_file'])){ self::$log_file = $this->setting['log_file']; unset($this->setting['log_file']); } if(isset($this->setting['max_connection'])){ $this->max_connection = $this->setting['max_connection']; unset($this->setting['max_connection']); } if(isset($this->setting['smtp_host'])){ $this->smtp_host = $this->setting['smtp_host']; unset($this->setting['smtp_host']); } if(isset($this->setting['smtp_port'])){ $this->smtp_port = $this->setting['smtp_port']; unset($this->setting['smtp_port']); } if(isset($this->setting['smtp_user'])){ $this->smtp_user = $this->setting['smtp_user']; unset($this->setting['smtp_user']); } if(isset($this->setting['smtp_pass'])){ $this->smtp_pass = $this->setting['smtp_pass']; unset($this->setting['smtp_pass']); } if(isset($this->setting['smtp_from'])){ $this->smtp_from = $this->setting['smtp_from']; unset($this->setting['smtp_from']); } $this->server->set($this->setting); $version = explode('.', SWOOLE_VERSION); if($version[0] == 1 && $version[1] $version