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

猜你喜欢

转载自www.cnblogs.com/kkform/p/9236102.html