最新消息:觉得本站不错的话 记得收藏哦 博客内某些功能仅供测试 讨论群:135931704 快养不起小站了 各位有闲钱就打赏下把 My Email weicots#gmail.com Please replace # with @

一个简单的swoole 服务器示例

服务端开发 ajiang-tuzi 937浏览

运行流程图

swoole

进程/线程结构图

process

一个简单的示例


/**
 * Created by PhpStorm.
 * User:ajiang
 * Date: 2017/11/22 0022
 * Time: 11:43
 *  一个简单的swoole 服务器示例
 */
<?php
require_once dirname(__FILE__) . "/config/Bootstrap.php";


class Server
{
    private $serv;
    public $setting;
    public $swooleTaskPidPath;
    public $logger;

    public function __construct($ip, $port)
    {
        $this->swooleTaskPidPath = BASE_PATH . DS . \Weicot\Core\Initialization::SWOOLE_TASK_PID_PATH;
        $this->logger = new \Weicot\Core\Logger();
        $swooleLogger = BASE_PATH . DS . "var/swoole/swoole_" . date('Ymd') . ".log";
        $this->setting = [
            'host' => $ip,
            'port' => $port,
            'env' => 'dev', //环境 dev|test|prod
            'process_name' => "test",  //swoole 进程名称
            'worker_num' => 4, //一般设置为服务器CPU数的1-4倍
            'task_worker_num' => 4,  //task进程的数量
            'task_ipc_mode' => 3,  //使用消息队列通信,并设置为争抢模式
            'task_max_request' => 10000,  //task进程的最大任务数
            //     'daemonize' => 1, //以守护进程执行
            'max_request' => 10000,
            'dispatch_mode' => 2,
            'log_file' => $swooleLogger,  //日志
        ];

        $this->config();

        $this->sevice();
    }

    /**
     *
     */
    public function config()
    {
        $this->serv = new swoole_server($this->setting["host"], $this->setting["port"]);
        $this->serv->set([
            'worker_num' => $this->setting['worker_num'], //工作进程数量
            'task_worker_num' => $this->setting['task_worker_num'],
            'task_ipc_mode ' => $this->setting['task_ipc_mode'],
            'task_max_request' => $this->setting['task_max_request'],
            'daemonize' => $this->setting['daemonize'], //是否作为守护进程
            'max_request' => $this->setting['max_request'],
            'dispatch_mode' => $this->setting['dispatch_mode'],
            'log_file' => $this->setting['log_file'],
        ]);
    }

    public function getServiceInfo()
    {
        $this->outInfo("Swoole Version:" . swoole_version());       //输出swoole的版本
        $ipString = $this->logger->arryToString(swoole_get_local_ip(), "\r\n"); //输出本机iP
        $this->outInfo("Local Ip:" . $ipString);
    }

    /**
     *
     */
    public function sevice()
    {
        //增加新的监控的ip:post:mode
        $this->serv->addlistener("::1", 9500, SWOOLE_SOCK_TCP);
        //监听事件
        $this->serv->on('Start', array($this, 'onStart'));    //启动server时候会触发。
        $this->serv->on('Connect', array($this, 'onConnect'));   //client连接成功后触发。
        $this->serv->on('Receive', array($this, 'onReceive'));    //接收client发过来的请求
        $this->serv->on('ManagerStart', array($this, 'onManagerStart')); //master进程启动后, fork出Manager进程, 然后触发ManagerStart
        $this->serv->on('WorkerStart', array($this, 'onWorkerStart'));   //manager进程启动,启动work进程的时候调用 workid表示第几个id, 从0开始。
        $this->serv->on('WorkerStop', array($this, 'onWorkerStop'));    //当一个work进程死掉后,会触发
        $this->serv->on('task', array($this, 'onTask'));    //开始任务
        $this->serv->on('finish', array($this, 'onFinish'));    ////TDDO 任务结束之后处理任务或者回调
        $this->serv->on('Shutdown', array($this, 'onShutdown')); //关闭服务器时触发
        $this->serv->on('Close', array($this, 'onClose'));  //客户端断开触发
        $this->serv->start();  //启动
    }

    /**
     * @param $info
     * @param bool $out
     */
    public function outInfo($info, $out = false)
    {
        if (!$this->_setting['daemonize']) {
            $this->logger->outInfo("Swoole SPE:" . getmygid(), $info);
        } elseif ($out) {
            $this->logger->outInfo("Swoole SPE:" . getmygid(), $info);
        }
    }

    /**
     * 设置swoole进程名称
     * @param string $name swoole进程名称
     */
    private function setProcessName($name)
    {
        if (function_exists('cli_set_process_title')) {
            cli_set_process_title($name);
        } else {
            if (function_exists('swoole_set_process_name')) {
                swoole_set_process_name($name);
            } else {
                trigger_error(__METHOD__ . " failed. require cli_set_process_title or swoole_set_process_name.");
            }
        }
    }

    /**
     * Server启动在主进程的主线程回调此函数
     * @param $serv
     */
    public function onManagerStart(\swoole_server $server, $workerId)
    {
        $this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server manager worker start\n");
        $this->setProcessName($this->_setting['process_name'] . '-manager');
        // 引入SP入口文件
        // require_once dirname(__FILE__) . "/config/Bootstrap.php";
    }

    /**
     * worker start 加载业务脚本常驻内存
     * @param $server
     * @param $workerId
     */
    public function onWorkerStart($serv, $workerId)
    {
        if ($workerId >= $this->_setting['worker_num']) {
            $this->setProcessName($this->_setting['process_name'] . '-task');
        } else {
            $this->setProcessName($this->_setting['process_name'] . '-event');
        }
        $this->outInfo("Start Worker:" . $workerId);
    }

    /**
     * 当一个work进程死掉后,会触发
     * worker 进程停止
     * @param $server
     * @param $workerId
     */
    public function onWorkerStop($serv, $workerId)
    {
        $this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server[{$serv->setting['process_name']}  worker:{$workerId} shutdown\n");
        $this->outInfo('Worker Stop:' . $workerId, true);
    }

    //启动server时候会触发。
    public function onStart($serv)
    {
        $this->getServiceInfo();
        $this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server master worker start\n");
        $this->setProcessName($this->_setting['process_name'] . '-master');
        $pid = "{$serv->master_pid}\n{$serv->manager_pid}";  //记录进程id,脚本实现自动重启
        file_put_contents($this->swooleTaskPidPath, $pid);
    }

    /**
     * 监听连接进入事件
     * client连接成功后触发。
     * @param $serv
     * @param $fd
     */
    public function onConnect($serv, $fd, $from_id)
    {
        $this->outInfo('Date:' . date('Y-m-d H:i:s') . "\t swoole_server connect[" . $fd . "]\n");
        $a = $serv->send($fd, "Hello {$fd}!");
        // var_dump($a); //成功返回true
    }

    /**
     * 监听数据发送事件
     * 接收client发过来的请求
     * @param $serv
     * @param $fd
     * @param $from_id
     * @param $data
     */
    public function onReceive(swoole_server $serv, $fd, $from_id, $data)
    {
        echo "Get Message From Client {$fd}:{$data}\n";

        if (!$this->_setting['daemonize']) {
            echo "Get Message From Client {$fd}:{$data}\n\n";
        }
        $result = json_decode($data, true);
        switch ($result['action']) {
            case 'reload':  //重启
                $serv->reload();
                break;
            case 'close':  //关闭Server 关闭时
                $serv->shutdown();
                break;
            case 'status':  //状态
                $serv->send($fd, json_encode($serv->stats()));
                break;
            default:
                $serv->task($data);
                break;
        }
    }

    //客户端断开触发
    public function onClose($serv, $fd, $from_id)
    {
        echo "Client {$fd} close connection\n";
    }

    /***
     * 用来处理任务
     * @param $serv
     * @param $task_id
     * @param $from_id
     * @param $data
     * @return string
     *
     */
    public function onTask($serv, $task_id, $from_id, $data)
    {
        $this->outInfo("Task {$task_id} finish\r\n" . "Result: {$data}");
        echo "This Task {$task_id} from Worker {$from_id}\n";
        echo "Data: {$data}\n";
        $fd = json_decode($data, true);
        $serv->send($fd['fd'], "Data in Task {$task_id}");
        $serv->close($fd['fd']);
        echo "Task {$task_id}'s result";
        return "=====================";
    }

    /**
     * 监听连接Finish事件
     * @param $serv
     * @param $task_id
     * @param $data
     */
    public function onFinish($serv, $task_id, $data)
    {
        // TDDO: 任务结束之后处理任务或者回调
        //var_dump($data);
        //   $serv->close($data["fd"]);
        echo "Task {$task_id} finish\n";
        echo "Result: {$data}\n";
    }

    /**
     * 此事件在Server 关闭时以及  结束时发生
     */
    public function onShutdown($serv)
    {
        if (file_exists($this->swooleTaskPidPath)) {
            unlink($this->swooleTaskPidPath);
        }
        if (!$this->setting['daemonize']) {
            echo 'Date:' . date('Y-m-d H:i:s') . "\t swoole_server shutdown\n";
        }
    }
}


// 启动服务器
$server = new Server("192.168.1.111", "2015");



转载请注明:(●--●) Hello.My Weicot » 一个简单的swoole 服务器示例