swoole

安裝php

wget https://github.com/swoole/swoole-src/archive/v1.9.14.tar.gz
tar -zxvf v1.9.14.tar.gz
cd swoole-src-1.9.14/
phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make 
sudo make install
vi /usr/local/php/etc/php.ini
extension=swoole

使用git

服務sever.phpgithub

<?php
class Server
{
    private $ip = '127.0.0.1';
    private $port = '9901';
    private $manage_port = '9909';

    public function __construct($cmd) {
        switch ($cmd){
            case 'start':
                $this->start();
                break;
            default:
                $this->manager($cmd);
        }
    }

    private function start(){
        $server = new swoole_server($this->ip, $this->port);

        $server->set(array(
            'worker_num'       => 4,
            'task_worker_num'  => 12,
            'max_conn'         => 1000,
            'max_request'      => 10000,
            'debug_mode'       => 1,
            'open_eof_check'   => true,     //打開EOF檢測
            'package_eof'      => "\r\n",   //設置EOF
            'backlog' => 128,
            'daemonize'        => false, //Is start Daemon process
            'log_file'         => 'swoole.log',
        ));

        //增長監聽的端口
        $server->addlistener($this->ip, $this->manage_port, SWOOLE_SOCK_UDP);
        $server->on('Start',       array($this, 'onStart'));
        $server->on('WorkerStart', array($this, 'onWorkerStart'));
        $server->on('Receive',     array($this, 'onReceive'));
        $server->on('Task',        array($this, 'onTask'));
        $server->on('Finish',      array($this, 'onFinish'));
        $server->on('Packet',      array($this, 'onPacket'));
        $server->start();
    }

    /**
     * 內網管理
     *
     * @param $cmd
     * @throws Exception
     */
    private function manager($cmd){
        if(!in_array($cmd, array('reload'))) {
            exit('錯誤命令,僅支持start,stop,reload');
        }

        $client = new swoole_client(SWOOLE_SOCK_UDP, SWOOLE_SOCK_SYNC);
        $ret = $client->connect($this->ip, $this->manage_port, 0.5);
        if(!$ret) {
            throw new Exception($client->errCode);
        }
        $client->send("{$cmd}\r\n");
        $ret =  $client->recv();
        echo $ret . PHP_EOL;
    }

    public function onStart($server) {
        echo 'Server Start: ' . date('m-d H:i:s') . ' 主進程Pid:' . $server->master_pid . " 管理進程Pid:" . $server->manager_pid . PHP_EOL;
    }

    public function onWorkerStart($server) {
        if(function_exists('opcache_reset')){
            opcache_reset();
        }
        echo '運行onWorkerStart'.PHP_EOL;
        require_once 'reload.php';
    }

    public function onConnect($server, $fd){
        echo "Connected" . PHP_EOL;
    }

    public function onReceive($server, $fd, $from_id, $data){
        $server->task($data);
    }

    public function onClose($server, $fd, $from_id ) {
        echo "Client {$fd} close connection" . PHP_EOL;
    }

    public function onTask($server, $task_id, $from_id, $data) {
        $dataList = explode("\r\n", $data);
        foreach ($dataList as $row) {
            if(!empty($row)) {
                if(empty($row)) {
                    continue;
                }
                $handler = new a();
                $handler->handle($row);

            }
        }
        unset($row, $dataList, $handler);
        $server->finish("ok");
    }

    public function onFinish($server, $task_id, $data) {
        echo $task_id." complete!".$data . PHP_EOL;
    }

    /**
     * 監聽UDP數據包
     */
    public function onPacket($server, $data, $client_info) {
        $fd   = $client_info['address'];
        $port = $client_info['port'];

        $dataList = explode("\r\n", $data);
        foreach ($dataList as $row) {
            if(!empty($row)) {
                switch($row) {
                    case 'reload':
                        echo '服務器Worker重啓成功' . PHP_EOL;
                        $server->reload();
                        $server->sendto($fd, $port,'服務器Worker重啓成功');
                        break;
                    case 'stop':
                        echo '服務器Worker關閉成功' . PHP_EOL;
                        $server->stop();
                        $server->sendto($fd, $port,'服務器Worker關閉成功');
                        break;
                    default:
                        $server->sendto($fd, $port,'命令錯誤');
                        break;
                }
            }
        }
        unset($row,$dataList, $fd, $port);
    }
}


global $argv;
$startFile = $argv[0];

if(!isset($argv[1])) {
    exit("使用方法: php {$startFile} {start|stop|reload}\n");
}

new Server($argv[1]);

處理task的文件,能夠熱部署reload.phpbash

<?php

class a{

    public function handle($data){
        echo 'handing';
    }
}

客戶端服務器

/**
 * 設置waring等信息
 */
function warning_log($errno, $errstr, $errfile, $errline){
    file_put_contents('error.log',date("Y-m-d H:i:s")."#".$errno."#".$errstr."#".$errfile."#".$errline."\n",FILE_APPEND);
}
set_error_handler("warning_log",E_ALL);
$client = new swoole_client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
if (!$client->connect('127.0.0.1', 9901, 100))
{
    exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("message\r\n");
$client->close();

啓動swoole

php server.php startui

關閉this

php server.php stopspa

熱更新reload.php代碼debug

php server.php reload

ps:

1若是開啓opcache請在onWorkerStart中添加,不然會致使熱更新失敗

opcache_reset();

2. 上述演示代碼中reload.php中加載其餘的php文件,能夠不須要發送reload命令就能夠自動更新。

相關文章
相關標籤/搜索