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