laravel使用swoole


參考 參考2

另外主要用到artisan

首先創建SwooleCommand.php

<?php

namespace App\Console\Commands;

use App\Http\Controllers\SwooleHandler;use App\Models\Logs;
use App\Traits\TcpServer;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Symfony\Component\Console\Input\InputArgument;

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

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'this is command for swoole';

    protected $serv;
    /**
     * Create a new command instance.
     *
     * @return void
     */

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->fire();
    }

    public function fire(){
        $action = $this->argument('action');
        switch ($action){
            case 'start':
                $this->info("swoole observer started");
                $this->start();
                break;
            case 'stop':
                $this->info("stoped");
                break;
            case 'restart':
                $this->info("restarted");
                break;
            default:
                $this->error("unknown command");
        }

    }

    private function start(){
        Logs::truncate();//重啟cli后清空數據庫
        $this->serv = new \Swoole\Server(env('SWOOLE_SERVICE_ADDRESS', '127.0.0.1'), env('SWOOLE_SERVICE_PORT', 9503), SWOOLE_PROCESS);
        $this->serv->set([
            'worker_num' => 1,
            'heartbeat_check_interval' => 60, //心跳檢測
            'max_request' => 1000,
            'log_file' => './log/swoole.log',
        ]);
        $handler = new SwooleHandler();
        $this->serv->on('connect', [$handler, 'onConnect']);
        $this->serv->on('receive', [$handler, 'onReceive']);
        $this->serv->on('workerStart', [$handler, 'onWorkerStart']);
        $this->serv->on('close', [$handler, 'onClose']);
        $this->serv->start();
    }

    protected function getArguments()
    {
        return [[
            'action', InputArgument::REQUIRED, 'start|stop|restart'
        ]];
    }
}

SwooleHandler.php

<?php
/**
 * Created by PhpStorm.
 * User: liuning
 * Date: 2018/4/9
 * Time: 11:35
 */

namespace App\Http\Controllers;
use App\Models\Config;
use App\Models\Logs;use App\Modules\Meeting\Models\ReserveRecord;use App\Traits\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;

class SwooleHandler extends BaseController
{public function onConnect($server, $fd){
        echo "建立連接通道ID:$fd\n";
    }

    public function onWorkerStart($server, $workerId){
        echo "worker啟動了\n";
        //進程開啟時綁定定時器,只有workderId為0才添加定時器,避免重復添加
        if($workerId == 0){
            echo "定時開啟\n";
            swoole_timer_tick(10000, [$this, 'onTimer'], ['server'=>$server]);
        }
    }

    public function onReceive($server, $fd, $fromId, $data){
        //收到指令后處理操作
    }

    public function onTimer($timerId, $params){
        //循環定時任務
        echo "執行開門定時任務開始\n";
    }

    public function onClose($server, $fd){
        Logs::delLog($fd);//關閉通道
        //添加警報
        echo "斷開連接通道: {$fd}\n";
    }

    public function onTask($server, $task_id, $from_id, $data){
        echo "任務開始\n";
    }

    public function onFinish($server, $task_id, $data){
        echo "任務結束\n";
    }
}

在Kernel.php中新增命令

protected $commands = [
        SwooleCommand::class,
    ];

 

這樣就能在網站根目錄打開tcp服務了

/usr/local/php/bin/php artisan swoole start
或以下命令后台運行
nohup /usr/local/php/bin/php artisan swoole start  > dev/null 2>&1 &

如果想做指定用戶推送數據就得另辟蹊徑了,我創建了臨時客戶端與服務端建立連接。

同理先創建客戶端命令

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ClientCommand extends Command
{
    /**
     * The name and signature of the console command.
     * command+mac
     * @var string
     */
    protected $signature = 'send {ccc}';

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

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

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $command = $this->argument('ccc');
        $client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
        $client->on("connect", function($cli)use($command) {
            $cli->send(fromateSendCode($command));
        });
        $client->on("receive", function($cli, $data){
            //處理$data
            //echo 輸出
        });
        $client->on("error", function($cli){
            echo "connect failed\n";
        });
        $client->on("close", function($cli){
            //echo "connection close\n";
        });
        $client->connect(env('SWOOLE_CLIENT_ADDRESS', '127.0.0.1'), env('SWOOLE_SERVICE_PORT', 9503), 0.5);
    }

    protected function getArguments()
    {
        return [[
            'ccc', InputArgument::REQUIRED
        ]];
    }
}

這樣就能用命令與服務端建立鏈接了

/usr/local/php/bin/php artisan send 111

這樣客戶端會一直與服務器建立連接,直到服務端主動關閉連接。所以需要在處理完客戶端請求后給客戶端發送數據,客戶端收到后主動與服務端斷開連接。

也可以調用代碼來建立連接

function doShell($command){
    $proPath = env('PRO_PATH', '/mnt/hgfs/www/blog');
    $phpPath = env('PHP_PATH', '/usr/local/php/bin/php');
    return shell_exec('cd '.$proPath.'; '.$phpPath.' artisan send '.$command);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM