Laravel-swoole

PHP_LHF發表於2020-07-15

使用laravel-swoole時查詢各種資料發現寫的都不完整,寫的不是伺服器端怎麼安裝swoole擴充套件,要不就是寫的不完整。

首先分析使用swoole需要用到的各種擴充套件。

  1. 首先需要服務端的支援,需要安裝phpswoole擴充套件
  2. 需要安裝swooletw/laravel-swoole
  3. 建立命令執行執行swoole進行

    分析好了那麼按照步驟執行就好

一: 伺服器端安裝PHP swoole 擴充套件

執行命令

pecl install swoole

修改php.ini 配置檔案

在最後新增這句

extension=swoole.so

!!!注意 重啟PHP 如果無法啟動,找到PHP的目錄下執行

sudo service php7.3-fpm restart

然後在虛擬機器上執行命令

php -m

看到如下圖表示swoole擴充套件裝好了

laravel-swoole

二:安裝laraveltw/laravel-swoole
在專案根目錄下使用 composer require swooletw/laravel-swoole -vvv安裝,最好加上 -vvv引數,因為安裝很慢,會給人一種沒有安裝被卡主的感覺(自己就經歷過)。最好別再本地執行或者在PHPstorm中執行。因為windows不支援laravel-swoole,會有各種問題。可以在虛擬機器的專案根目錄下執行(安裝時需要耐心)。
當在composer.josn中看到下圖示識的表示安裝成功

laravel-swoole

自定義命令

使用laravel自帶的方法artisan(真的很好用)

建立swoole命令 執行

php artisan make:command Swoole

會在app\Console\Command\目錄下生成Swoole檔案

<?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.
     * 這個方法中的邏輯需要自己寫
     * @return mixed
     */
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) {
            case 'close':
                break;
            default:
                $this->start();
                break;
        }
    }

    /**
     * 這個方法是自己新增的
     * 具體可參考 https://wiki.swoole.com/#/start/start_tcp_server
     */
    public function start()
    {
        // 這裡是監聽的服務埠號
        $this->ws = new swoole_websocket_server("0.0.0.0", 9502);
        //監聽WebSocket連線開啟事件
        $this->ws->on('open', function ($ws, $request) {

        });
        //監聽WebSocket訊息事件
        $this->ws->on('message', function ($ws, $frame) {
            $this->info("client is SendMessage4545\n" . $frame);
        });
        //監聽WebSocket主動推送訊息事件
        $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);
                }
            }
        });
        //監聽WebSocket連線關閉事件
        $this->ws->on('close', function ($ws, $fd) {
            $this->info("client is close\n");
        });
        $this->ws->start();
    }
}

Kernel.php檔案中註冊這個Swoole類,

<?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');
    }
}

在虛擬機器的根目錄下執行 php artisan swoole start 就會開啟一個長起程式
到這裡伺服器和後端程式碼完成
現在需要一個前端頁來實現長連結,前端程式碼很簡單

<!doctype html>
<html>

<head>
    <title>測試WebSocket</title>
</head>
    <div id="WebSocket"></div>
<body>
    <script>
    var ws = new WebSocket("ws://test.in:9502");
    ws.onopen = function(event) {
        console.log("客戶端已連線上!");
        ws.send("hello server,this is client!"); //客戶端給服務端推送訊息
    };
    ws.onmessage = function(event) {
        var parent = document.getElementById('WebSocket');
        var div = document.createElement("div");
        div.innerHTML = event.data
        parent.appendChild(div);
        console.log("伺服器傳過來的資料是:" + event.data);
    }

    ws.onclose = function(event) {
        console.log("連線已關閉");
    };
    </script>
</body>

websocket 檢測的是埠只要通過這個埠傳送資料都會獲取到。到此,larave-swoole前後端長連結實現。希望可以幫到大家。

本作品採用《CC 協議》,轉載必須註明作者和本文連結