另外主要用到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); }