laravel-swoole extension installation + php installation Swoole extension

Install swoole extension

Two methods to install php extension swoole

Check whether the Swoole PHP extension is enabled on the server
php -i | grep swoole

1. Install using pecl command

pecl install swoole

2. Manual compilation and installation

Use the following command to download the swoole installation package

git clone https://github.com/swoole/swoole-src.git

Unzip the source code and enter the directory

tar -zxvf swoole-src.tar.gz
cd swoole-src

Execute the following command

phpize
./configure
make
make install

Modify the php.ini file and add this sentence at the end

extension=swoole.so

Save, restart php-fpm and execute the following command

php -m

As shown in the picture below, it means that the php extension swoole has been installed.

Install laravel-swoole

Install laravel extension using following command

composer require swooletw/laravel-swoole

Add the providers array in config/app.php

SwooleTW\Http\LaravelServiceProvider::class

Publish the configuration file and modify the port number to 9052

php artisan vendor:publish --tag=laravel-swoole

Nginx reverse proxy

Forward the url request to the swoole service address 127.0.0.1:9502

location /sw {
    proxy_pass http://127.0.0.1:9052;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    rewrite /sw/(.*) /$1 break;
    proxy_redirect off;
}

Check whether the firewall is turned on on the server. If the firewall is turned on, the server firewall opens port 9052.

Usage examples

Use laravel’s own method artisan

Create the swoole using the following command

php artisan make:command Swoole

The Swoole file will be generated in the app\Console\Command\ directory

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use swoole_websocket_server;

class Swoole extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'swoole {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     * The logic in this method needs to be written by yourself
     * @return mixed
     */
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) {
            case 'close':
                break;
            default:
                $this->start();
                break;
        }
    }

    /**
     * This method is newly added by myself
     * For details, please refer to https://wiki.swoole.com/#/start/start_tcp_server
     */
    public function start()
    {
        //Here is the listening service port number
        $this->ws = new swoole_websocket_server("0.0.0.0", 9502);
        //Listen to the WebSocket connection open event
        $this->ws->on('open', function ($ws, $request) {

        });
        //Listen to WebSocket message events
        $this->ws->on('message', function ($ws, $frame) {
            $this->info("client is SendMessage4545\\
" . $frame);
        });
        //Listen to WebSocket active push message events
        $this->ws->on('request', function ($request, $response) {
            $scene = $request->post['scene'];
            foreach ($this->ws->connections as $fd) {
                if ($this->ws->isEstablished($fd)) {
                    $this->ws->push($fd, $scene);
                }
            }
        });
        //Listen to the WebSocket connection closing event
        $this->ws->on('close', function ($ws, $fd) {
            $this->info("client is close\\
");
        });
        $this->ws->start();
    }
}

Register this Swoole class in the Kernel.php file,

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        //
        \App\Console\Commands\RedisSubscribe::class,
        \App\Console\Commands\Swoole::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param \Illuminate\Console\Scheduling\Schedule $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        // ->hourly();
    }

    /**
     * Register the commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        $this->load(__DIR__.'/Commands');

        require base_path('routes/console.php');
    }
}

Executing the following command in the root directory will start a long process

php artisan swoole start

If the above command does not work then try the following command

nohup php artisan swoole:http start & amp;

To restart the swoole service, please use the following command

php artisan swoole:http restart

If the above command does not take effect after restarting, try the following command

nohup php artisan swoole:http restart & amp;

To stop the swoole service, please use the following command

php artisan swoole stop

If the above command does not work, try the following command

nohup php artisan swoole:http stop & amp;

Front-end page implements long links

<!doctype html>
<html>

<head>
    <title>Testing WebSocket</title>
</head>
    <div id="WebSocket"></div>
<body>
    <script>
    var ws = new WebSocket("your domain name/sw");
    ws.onopen = function(event) {
        console.log("The client is connected!");
        ws.send("hello server, this is client!"); //The client pushes messages to the server
    };
    ws.onmessage = function(event) {
        var parent = document.getElementById('WebSocket');
        var div = document.createElement("div");
        div.innerHTML = event.data
        parent.appendChild(div);
        console.log("The data sent from the server is:" + event.data);
    }

    ws.onclose = function(event) {
        console.log("Connection closed");
    };
    </script>
</body>

websocket detects the port and will get it as long as data is sent through this port. At this point, larave-swoole implements front-end and back-end long links. Hope it could help everyone.