1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
| <?php
namespace App\Console\Commands;
use Illuminate\Console\Command; use Swoole\Process;
class WebSocket extends Command { private $ws; private $pid_file; /** * The name and signature of the console command. * * @var string */ protected $signature = 'swoole {action}';
/** * The console command description. * * @var string */ protected $description = 'WebSocket';
public function __construct() { parent::__construct(); // 设置进程文件 $this->pid_file = __DIR__.'/../../../storage/swoole_websocket.pid'; }
public function handle() { $action = $this->argument('action'); switch ($action) { case 'stop': $this->stop(); break; case 'start': //启动命令 $this->start(); break; default: $this->error('没有' . $action . '这个命令'); break; } }
public function start() { $pid = $this->getPid(); $log = app('log')->channel('webSocket');
//检测服务是否启动 if ($pid && Process::kill($pid, 0)) { $this->error('服务已启动'); exit; }
//创建websocket服务器对象,监听0.0.0.0:9502端口 $this->ws = new \swoole_websocket_server("0.0.0.0", 9502);
$this->ws->set([ 'worker_num'=>8, 'daemonize' =>1, 'max_request'=>1000, 'dispatch_mode'=>2, 'pid_file' =>$this->pid_file, ]);
//监听WebSocket连接打开事件 $this->ws->on('open', function ($ws, $request) use ($log) { $log->debug($request->fd . "连接成功"); // $ws->push($request->fd, "hello, welcome\n"); });
//监听WebSocket消息事件 $this->ws->on('message', function ($ws, $frame) { //fd绑定客户端传过来的标识uid $ws->bind($frame->fd, $frame->data); });
$this->ws->on('request', function ($request, $response) use ($log) { $data = $request->post['data']; // 获取值 // 循环已连接的客户,向指定客户推送消息 foreach ($this->ws->connections as $fd) { // 检查连接是否为有效的 WebSocket 客户端连接 if ($this->ws->isEstablished($fd)) { // 获取连接信息 $clientInfo = $this->ws->connection_info($fd); if (array_key_exists('uid', $clientInfo) && (int)$clientInfo['uid'] === (int)$request->post['uid']) { $this->ws->push($fd, $data); } } } $log->debug("client is PushMessage\n".$data); });
//监听WebSocket连接关闭事件 $this->ws->on('close', function ($ws, $fd) use ($log) { $log->debug("client:{$fd} is closed\n"); });
$this->ws->start(); }
public function stop() { if (!$pid = $this->getPid()) { $this->error('没有服务id'); exit; } //关闭服务 if (Process::kill($pid)) { $this->info('服务已停止'); exit; } $this->info('停止服务失败'); }
// 获取进程pid private function getPid() { return file_exists($this->pid_file) ? file_get_contents($this->pid_file) : false; }
public static function push($data) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "http://127.0.0.1:9502"); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HEADER, 1); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_POSTFIELDS, $data); curl_exec($curl); curl_close($curl); } }
|