PHP asynchronous, parallel, high-performance network communication engine, written in pure C language, provides PHP language asynchronous multithreaded server, asynchronous TCP/UDP network client, asynchronous MySQL, asynchronous Redis, database connection pool, AsyncTask, message queue, ms timer, asynchronous file read and write, Asynchronous DNS query. Swoole has a built-in Http/WebSocket server/client, Http2.0 server.

Premise:

Make sure your environment is already installed with swoole extension! If you do not know how to install please refer to baidu online below:

The blogger is installed in Ubuntu:

When installing PHP, try to use pecl installation, one-click installation, not so much trouble. Endurance exercise students can try their own compilation and installation, although it is relatively simple, but prone to some version of the problem.

One-click installation:

/usr/local/php/bin/pecl install swoole
Copy the code

Ensure the swoole. So files in/usr/local/PHP/lib/PHP/extensions/no – debug – non – ZTS – 20131226 (in) generally below, not in words here

Then in PHP. The ini file to add the extension = “/ usr/local/PHP/lib/PHP/extensions/no – debug – non – ZTS – 20131226 / swoole. So”. Then restart phP-FPM to load the Swoole extension. Use the PHP -m command to view the loaded module to see if it swoole

The body of the

Swoole is mainly divided into client and server. The client sends tasks to the resource pool, and the server handles tasks from the resource pool. Both listen on the same port number.

Server: The Server defines a command swoole-server that needs to be run as a guard process, always listening to port 9800. As long as there is a client method, the client sends tasks, the Server can capture and process.

The Server life cycle is divided into Receive, Task, and Finish, as detailed in the code and comments below.

<? php namespace app\console\swoole; use think\console\Command; use think\console\Input; use think\console\Output; use think\Log; class ServerCommand extends Command { private$serv;
    protected $isLog = true; / / is writinglog, set the production environment tofalse


    protected function configure() {
        $this->setName('swoole-server') - >setDescription('Swoole server');
    }

    protected function execute(Input $input, Output $output) {
        $this->serv = new \swoole_server('0.0.0.0', 9800); // Allow all IP access$this->logFile = RUNTIME_PATH . 'swoole-log' . DS . date('Ymd').'.log';
        $this->serv->set([
            'worker_num'=> 12. // Generally, set this parameter to 1-4 times the number of cpus on the server'task_worker_num'=> 20, // Number of task processes (common tasks are blocked synchronously, can be set to single-process single-thread)'daemonize'= >true.'open_eof_split'= >true// Open the eof_split check'package_eof'=> PHP_EOL,// set EOF to daemon //'task_ipc_mode'=> 1, // Use Unix socket for communication, default mode'log_file'= >$this->logOnConnect /onClose is blocked when dispatch_mode=1/3. / / reason is that there is no guarantee that the two kinds of patterns onConnect onClose/onReceive sequence, the request and response of the server program, please do not use pattern 1 or 3) / /'dispatch_mode'=> 2, // Fixed mode, assign worker according to connected file descriptor. This ensures that data sent from the same connection will only be processed by the same worker.$this->serv->on('Receive'[$this.'onReceive'
        ]);
        $this->serv->on('Task'[$this.'onTask'
        ]);
        $this->serv->on('Finish'[$this.'onFinish'
        ]);
        $this->serv->start(); } /** * test use, build environment do not use, very low efficiency * @param$strLogContext
     */
    public function error($strLogContext) {
        $fp = @fopen($this->logFile, "a+");
        @fputs($fp.$strLogContext . PHP_EOL);
        @fclose($fp); } /** * this function is called when data is received, which occurs in worker processes *$server, swoole_server object *$fd, file descriptor * for TCP client connections$from_id, the Reactor thread ID * where the TCP connection is located$data, the received data content, may be text or binary content */ publicfunction onReceive($serv.$fd.$from_id.$data) {
        $str = PHP_EOL . "=========== onReceive ============" . PHP_EOL;
        $str. ="Get Message From Client {$fd}, {$data}" . '--fromid--' . $from_id . PHP_EOL;
        Log::record($str.'swoole');
        $serv->task($data); } /** * is called within the task_worker process. The worker process can use the swoole_server_task function to post a new task to the task_worker process. When the current Task process calls the onTask callback, the state of the process changes to busy and no new tasks are received. When the onTask function returns, the state of the process changes to idle and continues to receive new tasks. *$task_idIs the task ID, automatically generated within the Swoole extension to distinguish between different tasks.$task_idand$src_worker_idDifferent worker processes may have the same task ID *$src_worker_idFrom which worker process *$dataIs the content of the task */ publicfunction onTask($serv.$task_id.$src_worker_id.$data) {
        $array = json_decode($data.true);
        $str   = "=========== onTask ============" . PHP_EOL;
        $str .= var_export($array, 1) . PHP_EOL;
        Log::record($str.'swoole');

        return $array; } /** * When the task is completed in the task_worker, the task sends the result of the task to the worker * via the swoole_server-> Finish () method$task_idIs the task ID *$dataIs the result content of the task processing (that is, the onTask() function)return*/ publicfunction onFinish($serv.$task_id.$data) {
        if($data['errno'] > 0) {
            $str = "OnFinish ERROR: {$task_id}" . json_encode($data).'|' . date('Y-m-d H:i:s') . PHP_EOL;
            Log::record(['more_info'= > [$str . '|' . date('Y-m-d H:i:s') . PHP_EOL]], 'elk'); Log::save(); }}}Copy the code

The client sends tasks to the process pool and also listens on port 9800.

The following demo code defines a Command for the client. The actual business can also call _sendData($data) method directly in the business logic. The premise is that the client class does not inherit the Command class, otherwise it will fail.

<? php /** * Created by PhpStorm. * Date: 2017/2/15 * Time: 14:26 */ namespace app\console\swoole; use think\console\Command; use think\console\Input; use think\console\Output; use think\Log; class ClientCommand extends Command{ protectedfunction configure() {
        $this->setName('swoole-client') - >setDescription('Swoole client');
    }

    protected function execute(Input $input, Output $output) {
        Log::record('swoole-client'.'swoole');
        $data= [1, 2, 3];$this->_sendData(json_encode($data));
    }


    private function _sendData($data) {
        $client = new \swoole_client(SWOOLE_SOCK_TCP);
        $client->connect('127.0.0.1', 9800, 1);
        $client->send($data.PHP_EOL); }}Copy the code

Method of use

With the above two commands defined, you are ready to execute them.

Run server first in your project and let it start listening

php think swoole-server
Copy the code

Then execute the client to start the delivery task.

php think swoole-client
Copy the code

You can then see the execution log in the log:

Source address: git.oschina.net/chenjunlian…