欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

PHP 进行统一邮箱登陆的代理实现(swoole),

程序员文章站 2022-06-12 15:58:56
...

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