From 5d6b2f75eb8658369979cc02263e3e27e7d1c6e6 Mon Sep 17 00:00:00 2001 From: Marcos Marcolin Date: Mon, 17 Jul 2023 21:03:05 -0300 Subject: [PATCH 1/2] refactor: code improvements with php_codesniffer without affecting logic, part 1. --- .gitattributes | 1 + composer.json | 37 ++- phpcs.xml | 33 +++ src/ChannelAdapter.php | 105 ++++---- src/Client.php | 269 ++++++++++---------- src/Debug.php | 8 +- src/DefaultAdapter.php | 114 ++++----- src/Engine/Engine.php | 200 +++++++-------- src/Engine/Parser.php | 257 +++++++++---------- src/Engine/Protocols/Http/Request.php | 23 +- src/Engine/Protocols/Http/Response.php | 173 ++++++------- src/Engine/Protocols/SocketIO.php | 134 ++++------ src/Engine/Protocols/WebSocket.php | 37 ++- src/Engine/Protocols/WebSocket/RFC6455.php | 68 ++--- src/Engine/Socket.php | 110 ++++---- src/Engine/Transport.php | 35 ++- src/Engine/Transports/Polling.php | 152 +++++------ src/Engine/Transports/PollingJsonp.php | 49 ++-- src/Engine/Transports/PollingXHR.php | 55 ++-- src/Engine/Transports/WebSocket.php | 35 +-- src/Event/Emitter.php | 81 +++--- src/Nsp.php | 98 ++++--- src/Parser/Decoder.php | 119 +++++---- src/Parser/Encoder.php | 39 ++- src/Parser/Parser.php | 94 +++---- src/Socket.php | 281 ++++++++++----------- src/SocketIO.php | 110 ++++---- 27 files changed, 1302 insertions(+), 1415 deletions(-) create mode 100644 phpcs.xml diff --git a/.gitattributes b/.gitattributes index aa8eade..83846f0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,3 +2,4 @@ /docs/ export-ignore /examples/ export-ignore /tests/ export-ignore +/phpcs.xml export-ignore diff --git a/composer.json b/composer.json index ac6aa39..ec221df 100644 --- a/composer.json +++ b/composer.json @@ -1,14 +1,29 @@ { - "name" : "workerman/phpsocket.io", - "type" : "library", - "keywords": ["socket.io"], - "homepage": "http://www.workerman.net", - "license" : "MIT", - "require": { - "workerman/workerman" : "^4.0.0", - "workerman/channel" : ">=1.0.0" - }, - "autoload": { - "psr-4": {"PHPSocketIO\\": "./src"} + "name": "workerman/phpsocket.io", + "description": "A server side alternative implementation of socket.io in PHP based on Workerman", + "type": "library", + "keywords": [ + "socket.io", + "phpsocket.io", + "workerman", + "sockets", + "async", + "stream", + "server", + "non-blocking" + ], + "homepage": "https://www.workerman.net", + "license": "MIT", + "require": { + "workerman/workerman": "^4.0.0", + "workerman/channel": ">=1.0.0" + }, + "autoload": { + "psr-4": { + "PHPSocketIO\\": "./src" } + }, + "require-dev": { + "squizlabs/php_codesniffer": "^3.7" + } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..209dc87 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,33 @@ + + + IXC Soft Coding Standard + + + + + + */tests/* + */vendor/* + */examples/* + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ChannelAdapter.php b/src/ChannelAdapter.php index 61a79d7..6077c40 100644 --- a/src/ChannelAdapter.php +++ b/src/ChannelAdapter.php @@ -1,63 +1,65 @@ _channelId = (function_exists('random_int') ? random_int(1, 10000000): rand(1, 10000000)) . "-" . (function_exists('posix_getpid') ? posix_getpid(): 1); + $this->_channelId = (function_exists('random_int') ? random_int(1, 10000000) : rand(1, 10000000)) . "-" . (function_exists('posix_getpid') ? posix_getpid() : 1); \Channel\Client::connect(self::$ip, self::$port); - \Channel\Client::$onMessage = array($this, 'onChannelMessage'); + \Channel\Client::$onMessage = [$this, 'onChannelMessage']; \Channel\Client::subscribe("socket.io#/#"); Debug::debug('ChannelAdapter __construct'); } - + public function __destruct() { Debug::debug('ChannelAdapter __destruct'); } - - public function add($id ,$room) + + public function add($id, $room) { $this->sids[$id][$room] = true; $this->rooms[$room][$id] = true; $channel = "socket.io#/#$room#"; \Channel\Client::subscribe($channel); } - + public function del($id, $room) { unset($this->sids[$id][$room]); unset($this->rooms[$room][$id]); - if(empty($this->rooms[$room])) - { + if (empty($this->rooms[$room])) { unset($this->rooms[$room]); $channel = "socket.io#/#$room#"; \Channel\Client::unsubscribe($channel); } } - + public function delAll($id) { - $rooms = isset($this->sids[$id]) ? array_keys($this->sids[$id]) : array(); - if($rooms) - { - foreach($rooms as $room) - { - if(isset($this->rooms[$room][$id])) - { + $rooms = isset($this->sids[$id]) ? array_keys($this->sids[$id]) : []; + if ($rooms) { + foreach ($rooms as $room) { + if (isset($this->rooms[$room][$id])) { unset($this->rooms[$room][$id]); $channel = "socket.io#/#$room#"; \Channel\Client::unsubscribe($channel); } - if(isset($this->rooms[$room]) && empty($this->rooms[$room])) - { + if (isset($this->rooms[$room]) && empty($this->rooms[$room])) { unset($this->rooms[$room]); } } @@ -67,58 +69,49 @@ public function delAll($id) public function onChannelMessage($channel, $msg) { - if($this->_channelId === array_shift($msg)) - { + if ($this->_channelId === array_shift($msg)) { //echo "ignore same channel_id \n"; return; } - + $packet = $msg[0]; - + $opts = $msg[1]; - - if(!$packet) - { + + if (! $packet) { echo "invalid channel:$channel packet \n"; return; } - - if(empty($packet['nsp'])) - { + + if (empty($packet['nsp'])) { $packet['nsp'] = '/'; } - - if($packet['nsp'] != $this->nsp->name) - { - echo "ignore different namespace {$packet['nsp']} != {$this->nsp->name}\n"; - return; + + if ($packet['nsp'] != $this->nsp->name) { + echo "ignore different namespace {$packet['nsp']} != {$this->nsp->name}\n"; + return; } - + $this->broadcast($packet, $opts, true); } - + public function broadcast($packet, $opts, $remote = false) { parent::broadcast($packet, $opts); - if (!$remote) - { + if (! $remote) { $packet['nsp'] = '/'; - - if(!empty($opts['rooms'])) - { - foreach($opts['rooms'] as $room) - { - $chn = "socket.io#/#$room#"; - $msg = array($this->_channelId, $packet, $opts); - \Channel\Client::publish($chn, $msg); - } - } - else - { - $chn = "socket.io#/#"; - $msg = array($this->_channelId, $packet, $opts); - \Channel\Client::publish($chn, $msg); + + if (! empty($opts['rooms'])) { + foreach ($opts['rooms'] as $room) { + $chn = "socket.io#/#$room#"; + $msg = [$this->_channelId, $packet, $opts]; + \Channel\Client::publish($chn, $msg); + } + } else { + $chn = "socket.io#/#"; + $msg = [$this->_channelId, $packet, $opts]; + \Channel\Client::publish($chn, $msg); } - } + } } } diff --git a/src/Client.php b/src/Client.php index 5078f79..96c8d16 100644 --- a/src/Client.php +++ b/src/Client.php @@ -1,5 +1,9 @@ server = $server; $this->conn = $conn; - $this->encoder = new \PHPSocketIO\Parser\Encoder(); - $this->decoder = new \PHPSocketIO\Parser\Decoder(); + $this->encoder = new Encoder(); + $this->decoder = new Decoder(); $this->id = $conn->id; $this->request = $conn->request; $this->setup(); Debug::debug('Client __construct'); } - -public function __destruct() -{ - Debug::debug('Client __destruct'); -} -/** - * Sets up event listeners. - * - * @api private - */ + public function __destruct() + { + Debug::debug('Client __destruct'); + } - public function setup(){ - $this->decoder->on('decoded', array($this,'ondecoded')); - $this->conn->on('data', array($this,'ondata')); - $this->conn->on('error', array($this, 'onerror')); - $this->conn->on('close' ,array($this, 'onclose')); + /** + * Sets up event listeners. + * + * @api private + */ + + public function setup() + { + $this->decoder->on('decoded', [$this, 'ondecoded']); + $this->conn->on('data', [$this, 'ondata']); + $this->conn->on('error', [$this, 'onerror']); + $this->conn->on('close', [$this, 'onclose']); } -/** - * Connects a client to a namespace. - * - * @param {String} namespace name - * @api private - */ + /** + * Connects a client to a namespace. + * + * @param {String} namespace name + * @api private + */ - public function connect($name){ - if (!isset($this->server->nsps[$name])) - { - $this->packet(array('type'=> Parser::ERROR, 'nsp'=> $name, 'data'=> 'Invalid namespace')); + public function connect($name) + { + if (! isset($this->server->nsps[$name])) { + $this->packet(['type' => Parser::ERROR, 'nsp' => $name, 'data' => 'Invalid namespace']); return; } $nsp = $this->server->of($name); - if ('/' !== $name && !isset($this->nsps['/'])) - { + if ('/' !== $name && ! isset($this->nsps['/'])) { $this->connectBuffer[$name] = $name; return; } - $nsp->add($this, $nsp, array($this, 'nspAdd')); + $nsp->add($this, $nsp, [$this, 'nspAdd']); } public function nspAdd($socket, $nsp) { $this->sockets[$socket->id] = $socket; $this->nsps[$nsp->name] = $socket; - if ('/' === $nsp->name && $this->connectBuffer) - { - foreach($this->connectBuffer as $name) - { + if ('/' === $nsp->name && $this->connectBuffer) { + foreach ($this->connectBuffer as $name) { $this->connect($name); } - $this->connectBuffer = array(); + $this->connectBuffer = []; } } - - -/** - * Disconnects from all namespaces and closes transport. - * - * @api private - */ - + /** + * Disconnects from all namespaces and closes transport. + * + * @api private + */ public function disconnect() { - foreach($this->sockets as $socket) - { + foreach ($this->sockets as $socket) { $socket->disconnect(); } - $this->sockets = array(); + $this->sockets = []; $this->close(); } -/** - * Removes a socket. Called by each `Socket`. - * - * @api private - */ - + /** + * Removes a socket. Called by each `Socket`. + * + * @api private + */ public function remove($socket) { - if(isset($this->sockets[$socket->id])) - { + if (isset($this->sockets[$socket->id])) { $nsp = $this->sockets[$socket->id]->nsp->name; unset($this->sockets[$socket->id]); unset($this->nsps[$nsp]); - } else { - //echo('ignoring remove for '. $socket->id); } } -/** - * Closes the underlying connection. - * - * @api private - */ - + /** + * Closes the underlying connection. + * + * @api private + */ public function close() { - if (empty($this->conn)) return; - if('open' === $this->conn->readyState) - { - //echo('forcing transport close'); - $this->conn->close(); - $this->onclose('forced server close'); + if (empty($this->conn)) { + return; + } + if ('open' === $this->conn->readyState) { + //echo('forcing transport close'); + $this->conn->close(); + $this->onclose('forced server close'); } } -/** - * Writes a packet to the transport. - * - * @param {Object} packet object - * @param {Object} options - * @api private - */ + /** + * Writes a packet to the transport. + * + * @param {Object} packet object + * @param {Object} options + * @api private + */ public function packet($packet, $preEncoded = false, $volatile = false) { - if(!empty($this->conn) && 'open' === $this->conn->readyState) - { - if (!$preEncoded) - { + if (! empty($this->conn) && 'open' === $this->conn->readyState) { + if (! $preEncoded) { // not broadcasting, need to encode $encodedPackets = $this->encoder->encode($packet); $this->writeToEngine($encodedPackets, $volatile); } else { // a broadcast pre-encodes a packet - $this->writeToEngine($packet); + $this->writeToEngine($packet); } - } else { - // todo check - // echo('ignoring packet write ' . var_export($packet, true)); } } - public function writeToEngine($encodedPackets, $volatile = false) + public function writeToEngine($encodedPackets, $volatile = false) { - if($volatile)echo new \Exception('volatile'); - if ($volatile && !$this->conn->transport->writable) return; + if ($volatile) { + echo new \Exception('volatile'); + } + if ($volatile && ! $this->conn->transport->writable) { + return; + } // todo check - if(isset($encodedPackets['nsp']))unset($encodedPackets['nsp']); - foreach($encodedPackets as $packet) - { - $this->conn->write($packet); + if (isset($encodedPackets['nsp'])) { + unset($encodedPackets['nsp']); + } + foreach ($encodedPackets as $packet) { + $this->conn->write($packet); } } - -/** - * Called with incoming transport data. - * - * @api private - */ - + /** + * Called with incoming transport data. + * + * @api private + */ public function ondata($data) { try { - // todo chek '2["chat message","2"]' . "\0" . '' + // todo chek '2["chat message","2"]' . "\0" . '' $this->decoder->add(trim($data)); - } catch(\Exception $e) { + } catch (\Exception $e) { $this->onerror($e); } } -/** - * Called when parser fully decodes a packet. - * - * @api private - */ - - public function ondecoded($packet) + /** + * Called when parser fully decodes a packet. + * + * @api private + */ + public function ondecoded($packet) { - if(Parser::CONNECT == $packet['type']) - { + if (Parser::CONNECT == $packet['type']) { $this->connect($packet['nsp']); } else { - if(isset($this->nsps[$packet['nsp']])) - { - $this->nsps[$packet['nsp']]->onpacket($packet); - } else { - //echo('no socket for namespace ' . $packet['nsp']); + if (isset($this->nsps[$packet['nsp']])) { + $this->nsps[$packet['nsp']]->onpacket($packet); } } } -/** - * Handles an error. - * - * @param {Objcet} error object - * @api private - */ - + /** + * Handles an error. + * + * @param {Objcet} error object + * @api private + */ public function onerror($err) { - foreach($this->sockets as $socket) - { + foreach ($this->sockets as $socket) { $socket->onerror($err); } $this->onclose('client error'); } -/** - * Called upon transport close. - * - * @param {String} reason - * @api private - */ - + /** + * Called upon transport close. + * + * @param {String} reason + * @api private + */ public function onclose($reason) { - if (empty($this->conn)) return; + if (empty($this->conn)) { + return; + } // ignore a potential subsequent `close` event $this->destroy(); // `nsps` and `sockets` are cleaned up seamlessly - foreach($this->sockets as $socket) - { + foreach ($this->sockets as $socket) { $socket->onclose($reason); } $this->sockets = null; } -/** - * Cleans up event listeners. - * - * @api private - */ - + /** + * Cleans up event listeners. + * + * @api private + */ public function destroy() { - if (!$this->conn) return; + if (! $this->conn) { + return; + } $this->conn->removeAllListeners(); $this->decoder->removeAllListeners(); $this->encoder->removeAllListeners(); diff --git a/src/Debug.php b/src/Debug.php index 43a11f3..bc5f0cd 100644 --- a/src/Debug.php +++ b/src/Debug.php @@ -1,12 +1,14 @@ nsp = $nsp; - $this->encoder = new Parser\Encoder(); - Debug::debug('DefaultAdapter __construct'); + $this->nsp = $nsp; + $this->encoder = new Parser\Encoder(); + Debug::debug('DefaultAdapter __construct'); } - + public function __destruct() { Debug::debug('DefaultAdapter __destruct'); } - + public function add($id, $room) { $this->sids[$id][$room] = true; $this->rooms[$room][$id] = true; } - + public function del($id, $room) { unset($this->sids[$id][$room]); unset($this->rooms[$room][$id]); - if(empty($this->rooms[$room])) - { + if (empty($this->rooms[$room])) { unset($this->rooms[$room]); } } public function delAll($id) { - $rooms = array_keys(isset($this->sids[$id]) ? $this->sids[$id] : array()); - foreach($rooms as $room) - { + $rooms = array_keys($this->sids[$id] ?? []); + foreach ($rooms as $room) { $this->del($id, $room); } unset($this->sids[$id]); @@ -47,60 +47,54 @@ public function delAll($id) public function broadcast($packet, $opts, $remote = false) { - $rooms = isset($opts['rooms']) ? $opts['rooms'] : array(); - $except = isset($opts['except']) ? $opts['except'] : array(); - $flags = isset($opts['flags']) ? $opts['flags'] : array(); - $packetOpts = array( + $rooms = $opts['rooms'] ?? []; + $except = $opts['except'] ?? []; + $flags = $opts['flags'] ?? []; + $packetOpts = [ 'preEncoded' => true, - 'volatile' => isset($flags['volatile']) ? $flags['volatile'] : null, - 'compress' => isset($flags['compress']) ? $flags['compress'] : null - ); + 'volatile' => $flags['volatile'] ?? null, + 'compress' => $flags['compress'] ?? null + ]; $packet['nsp'] = $this->nsp->name; $encodedPackets = $this->encoder->encode($packet); - if($rooms) - { - $ids = array(); - foreach($rooms as $i=>$room) - { - if(!isset($this->rooms[$room])) - { - continue; - } - - $room = $this->rooms[$room]; - foreach($room as $id=>$item) - { - if(isset($ids[$id]) || isset($except[$id])) - { - continue; + if ($rooms) { + $ids = []; + foreach ($rooms as $i => $room) { + if (! isset($this->rooms[$room])) { + continue; + } + + $room = $this->rooms[$room]; + foreach ($room as $id => $item) { + if (isset($ids[$id]) || isset($except[$id])) { + continue; } - if(isset($this->nsp->connected[$id])) - { - $ids[$id] = true; - $this->nsp->connected[$id]->packet($encodedPackets, $packetOpts); - } - } - } - } else { - foreach($this->sids as $id=>$sid) - { - if(isset($except[$id])) continue; - if(isset($this->nsp->connected[$id])) - { - $socket = $this->nsp->connected[$id]; - $volatile = isset($flags['volatile']) ? $flags['volatile'] : null; - $socket->packet($encodedPackets, true, $volatile); - } - } - } + if (isset($this->nsp->connected[$id])) { + $ids[$id] = true; + $this->nsp->connected[$id]->packet($encodedPackets, $packetOpts); + } + } + } + } else { + foreach ($this->sids as $id => $sid) { + if (isset($except[$id])) { + continue; + } + if (isset($this->nsp->connected[$id])) { + $socket = $this->nsp->connected[$id]; + $volatile = $flags['volatile'] ?? null; + $socket->packet($encodedPackets, true, $volatile); + } + } + } } - - public function clients($rooms, $fn) { - $sids = array(); + + public function clients($rooms, $fn) + { + $sids = []; foreach ($rooms as $room) { $sids = array_merge($sids, $this->rooms[$room]); } $fn(); } - } diff --git a/src/Engine/Engine.php b/src/Engine/Engine.php index 6e0db8e..a2c3099 100644 --- a/src/Engine/Engine.php +++ b/src/Engine/Engine.php @@ -1,32 +1,36 @@ 'polling', - 'websocket' => 'websocket' - ); + public static $allowTransports = [ + 'polling' => 'polling', + 'websocket' => 'websocket' + ]; - public static $errorMessages = array( + public static $errorMessages = [ 'Transport unknown', 'Session ID unknown', 'Bad handshake method', 'Bad request' - ); + ]; const ERROR_UNKNOWN_TRANSPORT = 0; @@ -36,20 +40,18 @@ class Engine extends Emitter const ERROR_BAD_REQUEST = 3; - public function __construct($opts = array()) + public function __construct($opts = []) { - $ops_map = array( - 'pingTimeout', - 'pingInterval', - 'upgradeTimeout', - 'transports', - 'allowUpgrades', - 'allowRequest' - ); - foreach($ops_map as $key) - { - if(isset($opts[$key])) - { + $ops_map = [ + 'pingTimeout', + 'pingInterval', + 'upgradeTimeout', + 'transports', + 'allowUpgrades', + 'allowRequest' + ]; + foreach ($ops_map as $key) { + if (isset($opts[$key])) { $this->$key = $opts[$key]; } } @@ -65,74 +67,64 @@ public function handleRequest($req, $res) { $this->prepare($req); $req->res = $res; - $this->verify($req, $res, false, array($this, 'dealRequest')); + $this->verify($req, $res, false, [$this, 'dealRequest']); } public function dealRequest($err, $success, $req) { - if (!$success) - { + if (! $success) { self::sendErrorMessage($req, $req->res, $err); return; } - if(isset($req->_query['sid'])) - { + if (isset($req->_query['sid'])) { $this->clients[$req->_query['sid']]->transport->onRequest($req); - } - else - { + } else { $this->handshake($req->_query['transport'], $req); } } protected function sendErrorMessage($req, $res, $code) { - $headers = array('Content-Type'=> 'application/json'); - if(isset($req->headers['origin'])) - { + $headers = ['Content-Type' => 'application/json']; + if (isset($req->headers['origin'])) { $headers['Access-Control-Allow-Credentials'] = 'true'; $headers['Access-Control-Allow-Origin'] = $req->headers['origin']; - } - else - { + } else { $headers['Access-Control-Allow-Origin'] = '*'; } $res->writeHead(403, '', $headers); - $res->end(json_encode(array( - 'code' => $code, - 'message' => isset(self::$errorMessages[$code]) ? self::$errorMessages[$code] : $code - ))); + $res->end( + json_encode( + [ + 'code' => $code, + 'message' => self::$errorMessages[$code] ?? $code + ] + ) + ); } protected function verify($req, $res, $upgrade, $fn) { - if(!isset($req->_query['transport']) || !isset(self::$allowTransports[$req->_query['transport']])) - { + if (! isset($req->_query['transport']) || ! isset(self::$allowTransports[$req->_query['transport']])) { return call_user_func($fn, self::ERROR_UNKNOWN_TRANSPORT, false, $req, $res); } $transport = $req->_query['transport']; - $sid = isset($req->_query['sid']) ? $req->_query['sid'] : ''; + $sid = $req->_query['sid'] ?? ''; /*if ($transport === 'websocket' && empty($sid)) { return call_user_func($fn, self::ERROR_UNKNOWN_TRANSPORT, false, $req, $res); }*/ - if($sid) - { - if(!isset($this->clients[$sid])) - { + if ($sid) { + if (! isset($this->clients[$sid])) { return call_user_func($fn, self::ERROR_UNKNOWN_SID, false, $req, $res); } - if(!$upgrade && $this->clients[$sid]->transport->name !== $transport) - { + if (! $upgrade && $this->clients[$sid]->transport->name !== $transport) { return call_user_func($fn, self::ERROR_BAD_REQUEST, false, $req, $res); } - } - else - { - if('GET' !== $req->method) - { - return call_user_func($fn, self::ERROR_BAD_HANDSHAKE_METHOD, false, $req, $res); + } else { + if ('GET' !== $req->method) { + return call_user_func($fn, self::ERROR_BAD_HANDSHAKE_METHOD, false, $req, $res); } return $this->checkRequest($req, $res, $fn); } @@ -141,17 +133,13 @@ protected function verify($req, $res, $upgrade, $fn) public function checkRequest($req, $res, $fn) { - if ($this->origins === "*:*" || empty($this->origins)) - { + if ($this->origins === "*:*" || empty($this->origins)) { return call_user_func($fn, null, true, $req, $res); } $origin = null; - if (isset($req->headers['origin'])) - { + if (isset($req->headers['origin'])) { $origin = $req->headers['origin']; - } - else if(isset($req->headers['referer'])) - { + } elseif (isset($req->headers['referer'])) { $origin = $req->headers['referer']; } @@ -160,23 +148,21 @@ public function checkRequest($req, $res, $fn) return call_user_func($fn, null, true, $req, $res); } - if ($origin) - { + if ($origin) { $parts = parse_url($origin); $defaultPort = 'https:' === $parts['scheme'] ? 443 : 80; - $parts['port'] = isset($parts['port']) ? $parts['port'] : $defaultPort; + $parts['port'] = $parts['port'] ?? $defaultPort; $allowed_origins = explode(' ', $this->origins); - foreach( $allowed_origins as $allow_origin ){ + foreach ($allowed_origins as $allow_origin) { $ok = $allow_origin === $parts['scheme'] . '://' . $parts['host'] . ':' . $parts['port'] || $allow_origin === $parts['scheme'] . '://' . $parts['host'] || $allow_origin === $parts['scheme'] . '://' . $parts['host'] . ':*' || $allow_origin === '*:' . $parts['port']; - if($ok){ - # 只需要有一个白名单通过,则都通过 + if ($ok) { + // 只需要有一个白名单通过,则都通过 return call_user_func($fn, null, $ok, $req, $res); } - } } call_user_func($fn, null, false, $req, $res); @@ -184,37 +170,34 @@ public function checkRequest($req, $res, $fn) protected function prepare($req) { - if(!isset($req->_query)) - { + if (! isset($req->_query)) { $info = parse_url($req->url); - if(isset($info['query'])) - { + if (isset($info['query'])) { parse_str($info['query'], $req->_query); } } } + /** + * @throws Exception + */ public function handshake($transport, $req) { - $id = bin2hex(pack('d', microtime(true)).pack('N', function_exists('random_int') ? random_int(1, 100000000): rand(1, 100000000))); + $id = bin2hex(pack('d', microtime(true)) . pack('N', function_exists('random_int') ? random_int(1, 100000000) : rand(1, 100000000))); if ($transport == 'websocket') { $transport = '\\PHPSocketIO\\Engine\\Transports\\WebSocket'; - } - elseif (isset($req->_query['j'])) - { + } elseif (isset($req->_query['j'])) { $transport = '\\PHPSocketIO\\Engine\\Transports\\PollingJsonp'; - } - else - { + } else { $transport = '\\PHPSocketIO\\Engine\\Transports\\PollingXHR'; } $transport = new $transport($req); - - $transport->supportsBinary = !isset($req->_query['b64']); + + $transport->supportsBinary = ! isset($req->_query['b64']); $socket = new Socket($id, $this, $transport, $req); - + /* $transport->on('headers', function(&$headers)use($id) { $headers['Set-Cookie'] = "io=$id"; @@ -223,7 +206,7 @@ public function handshake($transport, $req) $transport->onRequest($req); $this->clients[$id] = $socket; - $socket->once('close', array($this, 'onSocketClose')); + $socket->once('close', [$this, 'onSocketClose']); $this->emit('connection', $socket); } @@ -235,75 +218,62 @@ public function onSocketClose($id) public function attach($worker) { $this->server = $worker; - $worker->onConnect = array($this, 'onConnect'); + $worker->onConnect = [$this, 'onConnect']; } - + public function onConnect($connection) { - $connection->onRequest = array($this, 'handleRequest'); - $connection->onWebSocketConnect = array($this, 'onWebSocketConnect'); + $connection->onRequest = [$this, 'handleRequest']; + $connection->onWebSocketConnect = [$this, 'onWebSocketConnect']; // clean - $connection->onClose = function($connection) - { - if(!empty($connection->httpRequest)) - { + $connection->onClose = function ($connection) { + if (! empty($connection->httpRequest)) { $connection->httpRequest->destroy(); $connection->httpRequest = null; } - if(!empty($connection->httpResponse)) - { + if (! empty($connection->httpResponse)) { $connection->httpResponse->destroy(); $connection->httpResponse = null; } - if(!empty($connection->onRequest)) - { + if (! empty($connection->onRequest)) { $connection->onRequest = null; } - if(!empty($connection->onWebSocketConnect)) - { + if (! empty($connection->onWebSocketConnect)) { $connection->onWebSocketConnect = null; } }; } - + public function onWebSocketConnect($connection, $req, $res) { $this->prepare($req); - $this->verify($req, $res, true, array($this, 'dealWebSocketConnect')); + $this->verify($req, $res, true, [$this, 'dealWebSocketConnect']); } public function dealWebSocketConnect($err, $success, $req, $res) { - if (!$success) - { + if (! $success) { self::sendErrorMessage($req, $res, $err); return; } - - if(isset($req->_query['sid'])) - { - if(!isset($this->clients[$req->_query['sid']])) - { + if (isset($req->_query['sid'])) { + if (! isset($this->clients[$req->_query['sid']])) { self::sendErrorMessage($req, $res, 'upgrade attempt for closed client'); return; } $client = $this->clients[$req->_query['sid']]; - if($client->upgrading) - { + if ($client->upgrading) { self::sendErrorMessage($req, $res, 'transport has already been trying to upgrade'); return; } - if($client->upgraded) - { + if ($client->upgraded) { self::sendErrorMessage($req, $res, 'transport had already been upgraded'); return; } $transport = new WebSocket($req); $client->maybeUpgrade($transport); - } - else - { + } else { $this->handshake($req->_query['transport'], $req); } } diff --git a/src/Engine/Parser.php b/src/Engine/Parser.php index 74913e4..49f1f24 100644 --- a/src/Engine/Parser.php +++ b/src/Engine/Parser.php @@ -1,104 +1,98 @@ 0 // non-ws + , 'close' => 1 // non-ws + , 'ping' => 2 + , 'pong' => 3 + , 'message' => 4 + , 'upgrade' => 5 + , 'noop' => 6 + ]; - public static $packets=array( - 'open'=> 0 // non-ws - , 'close'=> 1 // non-ws - , 'ping'=> 2 - , 'pong'=> 3 - , 'message'=> 4 - , 'upgrade'=> 5 - , 'noop'=> 6 - ); - - public static $packetsList = array( - 'open', - 'close', - 'ping', - 'pong', - 'message', - 'upgrade', - 'noop' - ); - - public static $err = array( - 'type' => 'error', + public static $packetsList = [ + 'open', + 'close', + 'ping', + 'pong', + 'message', + 'upgrade', + 'noop' + ]; + + public static $err = [ + 'type' => 'error', 'data' => 'parser error' - ); + ]; public static function encodePacket($packet) { - $data = !isset($packet['data']) ? '' : $packet['data']; - return self::$packets[$packet['type']].$data; + $data = ! isset($packet['data']) ? '' : $packet['data']; + return self::$packets[$packet['type']] . $data; } - + /** * Encodes a packet with binary data in a base64 string * - * @param {Object} packet, has `type` and `data` + * @param {Object} packet, has `type` and `data` * @return {String} base64 encoded message */ - public static function encodeBase64Packet($packet) { - $data = isset($packet['data']) ? '' : $packet['data']; + $data = isset($packet['data']) ? '' : $packet['data']; return $message = 'b' . self::$packets[$packet['type']] . base64_encode($packet['data']); } - + /** * Decodes a packet. Data also available as an ArrayBuffer if requested. * * @return {Object} with `type` and `data` (if any) - * @api private + * @api private */ - - public static function decodePacket($data, $binaryType = null, $utf8decode = true) + public static function decodePacket($data, $binaryType = null, $utf8decode = true) { - // String data todo check if (typeof data == 'string' || data === undefined) - if ($data[0] === 'b') - { - return self::decodeBase64Packet(substr($data, 1), $binaryType); - } - - $type = $data[0]; - if (!isset(self::$packetsList[$type])) - { - return self::$err; - } - - if (isset($data[1])) - { - return array('type'=> self::$packetsList[$type], 'data'=> substr($data, 1)); - } - else - { - return array('type'=> self::$packetsList[$type]); - } + // String data todo check if (typeof data == 'string' || data === undefined) + if ($data[0] === 'b') { + return self::decodeBase64Packet(substr($data, 1), $binaryType); + } + + $type = $data[0]; + if (! isset(self::$packetsList[$type])) { + return self::$err; + } + + if (isset($data[1])) { + return ['type' => self::$packetsList[$type], 'data' => substr($data, 1)]; + } else { + return ['type' => self::$packetsList[$type]]; + } } - + /** * Decodes a packet encoded in a base64 string. * - * @param {String} base64 encoded message + * @param {String} base64 encoded message * @return {Object} with `type` and `data` (if any) */ - - public static function decodeBase64Packet($msg, $binaryType) + public static function decodeBase64Packet($msg, $binaryType) { $type = self::$packetsList[$msg[0]]; $data = base64_decode(substr($data, 1)); - return array('type'=> $type, 'data'=> $data); + return ['type' => $type, 'data' => $data]; } - + /** * Encodes multiple messages (payload). * @@ -112,110 +106,93 @@ public static function decodeBase64Packet($msg, $binaryType) * encoded strings are marked with a b before the length specifier * * @param {Array} packets - * @api private + * @api private */ - - public static function encodePayload($packets, $supportsBinary = null) + public static function encodePayload($packets, $supportsBinary = null) { - if ($supportsBinary) - { + if ($supportsBinary) { return self::encodePayloadAsBinary($packets); } - - if (!$packets) - { + + if (! $packets) { return '0:'; } - + $results = ''; - foreach($packets as $msg) - { + foreach ($packets as $msg) { $results .= self::encodeOne($msg, $supportsBinary); } return $results; } - - - public static function encodeOne($packet, $supportsBinary = null, $result = null) + + public static function encodeOne($packet, $supportsBinary = null, $result = null) { $message = self::encodePacket($packet, $supportsBinary, true); return strlen($message) . ':' . $message; } - - + /* * Decodes data when a payload is maybe expected. Possible binary contents are * decoded from their base64 representation * * @api public */ - - public static function decodePayload($data, $binaryType = null) + public static function decodePayload($data, $binaryType = null) { - if(!preg_match('/^\d+:\d/',$data)) - { + if (! preg_match('/^\d+:\d/', $data)) { return self::decodePayloadAsBinary($data, $binaryType); } - - if ($data === '') - { + + if ($data === '') { // parser error - ignoring payload return self::$err; } - + $length = '';//, n, msg; - - for ($i = 0, $l = strlen($data); $i < $l; $i++) - { + + for ($i = 0, $l = strlen($data); $i < $l; $i++) { $chr = $data[$i]; - - if (':' != $chr) - { + + if (':' != $chr) { $length .= $chr; - } - else - { - if ('' == $length || ($length != ($n = intval($length)))) - { + } else { + if ('' == $length || ($length != ($n = intval($length)))) { // parser error - ignoring payload return self::$err; } - + $msg = substr($data, $i + 1/*, $n*/); - - /*if ($length != strlen($msg)) + + /*if ($length != strlen($msg)) { // parser error - ignoring payload return self::$err; }*/ - - if (isset($msg[0])) - { + + if (isset($msg[0])) { $packet = self::decodePacket($msg, $binaryType, true); - - if (self::$err['type'] == $packet['type'] && self::$err['data'] == $packet['data']) - { + + if (self::$err['type'] == $packet['type'] && self::$err['data'] == $packet['data']) { // parser error in individual packet - ignoring payload return self::$err; } - + return $packet; } - + // advance cursor $i += $n; $length = ''; } } - - if ($length !== '') - { + + if ($length !== '') { // parser error - ignoring payload echo new \Exception('parser error'); return self::$err; } } - + /** * Encodes multiple messages (payload) as binary. * @@ -225,77 +202,73 @@ public static function decodePayload($data, $binaryType = null) * Example: * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers * - * @param {Array} packets + * @param {Array} packets * @return {Buffer} encoded payload - * @api private + * @api private */ - - public static function encodePayloadAsBinary($packets) + public static function encodePayloadAsBinary($packets) { $results = ''; - foreach($packets as $msg) - { + foreach ($packets as $msg) { $results .= self::encodeOneAsBinary($msg); } return $results; } - - public static function encodeOneAsBinary($p) + + public static function encodeOneAsBinary($p) { // todo is string or arraybuf $packet = self::encodePacket($p, true, true); - $encodingLength = ''.strlen($packet); + $encodingLength = '' . strlen($packet); $sizeBuffer = chr(0); - for ($i = 0; $i < strlen($encodingLength); $i++) - { + for ($i = 0; $i < strlen($encodingLength); $i++) { $sizeBuffer .= chr($encodingLength[$i]); } $sizeBuffer .= chr(255); - return $sizeBuffer.$packet; + return $sizeBuffer . $packet; } - + /* * Decodes data when a payload is maybe expected. Strings are decoded by * interpreting each byte as a key code for entries marked to start with 0. See * description of encodePayloadAsBinary * @api public */ - - public static function decodePayloadAsBinary($data, $binaryType = null) + public static function decodePayloadAsBinary($data, $binaryType = null) { $bufferTail = $data; - $buffers = array(); - - while (strlen($bufferTail) > 0) - { + $buffers = []; + + while (strlen($bufferTail) > 0) { $strLen = ''; $isString = $bufferTail[0] == 0; $numberTooLong = false; - for ($i = 1; ; $i++) - { + for ($i = 1;; $i++) { $tail = ord($bufferTail[$i]); - if ($tail === 255) break; + if ($tail === 255) { + break; + } // 310 = char length of Number.MAX_VALUE - if (strlen($strLen) > 310) - { + if (strlen($strLen) > 310) { $numberTooLong = true; break; } $strLen .= $tail; } - if($numberTooLong) return self::$err; + if ($numberTooLong) { + return self::$err; + } $bufferTail = substr($bufferTail, strlen($strLen) + 1); - + $msgLength = intval($strLen, 10); - + $msg = substr($bufferTail, 1, $msgLength + 1); $buffers[] = $msg; $bufferTail = substr($bufferTail, $msgLength + 1); } $total = count($buffers); - $packets = array(); - foreach($buffers as $i => $buffer) - { + $packets = []; + foreach ($buffers as $i => $buffer) { $packets[] = self::decodePacket($buffer, $binaryType, true); } return $packets; diff --git a/src/Engine/Protocols/Http/Request.php b/src/Engine/Protocols/Http/Request.php index ad197ad..1fd498a 100644 --- a/src/Engine/Protocols/Http/Request.php +++ b/src/Engine/Protocols/Http/Request.php @@ -1,4 +1,5 @@ connection = $connection; $this->parseHead($raw_head); } - + public function parseHead($raw_head) { $header_data = explode("\r\n", $raw_head); list($this->method, $this->url, $protocol) = explode(' ', $header_data[0]); list($null, $this->httpVersion) = explode('/', $protocol); unset($header_data[0]); - foreach($header_data as $content) - { - if(empty($content)) - { + foreach ($header_data as $content) { + if (empty($content)) { continue; } $this->rawHeaders[] = $content; diff --git a/src/Engine/Protocols/Http/Response.php b/src/Engine/Protocols/Http/Response.php index d529642..c2c4c41 100644 --- a/src/Engine/Protocols/Http/Response.php +++ b/src/Engine/Protocols/Http/Response.php @@ -1,6 +1,9 @@ headersSent) - { + if ($this->headersSent) { echo "header has already send\n"; return false; } $this->statusCode = $status_code; - if($reason_phrase) - { + if ($reason_phrase) { $this->_statusPhrase = $reason_phrase; } - if($headers) - { - foreach($headers as $key=>$val) - { + if ($headers) { + foreach ($headers as $key => $val) { $this->_headers[$key] = $val; } } @@ -53,32 +52,26 @@ public function writeHead($status_code, $reason_phrase = '', $headers = null) public function getHeadBuffer() { - if(!$this->_statusPhrase) - { - $this->_statusPhrase = isset(self::$codes[$this->statusCode]) ? self::$codes[$this->statusCode] : ''; + if (! $this->_statusPhrase) { + $this->_statusPhrase = self::$codes[$this->statusCode] ?? ''; } $head_buffer = "HTTP/1.1 $this->statusCode $this->_statusPhrase\r\n"; - if(!isset($this->_headers['Content-Length']) && !isset($this->_headers['Transfer-Encoding'])) - { + if (! isset($this->_headers['Content-Length']) && ! isset($this->_headers['Transfer-Encoding'])) { $head_buffer .= "Transfer-Encoding: chunked\r\n"; } - if(!isset($this->_headers['Connection'])) - { + if (! isset($this->_headers['Connection'])) { $head_buffer .= "Connection: keep-alive\r\n"; } - foreach($this->_headers as $key=>$val) - { - if($key === 'Set-Cookie' && is_array($val)) - { - foreach($val as $v) - { + foreach ($this->_headers as $key => $val) { + if ($key === 'Set-Cookie' && is_array($val)) { + foreach ($val as $v) { $head_buffer .= "Set-Cookie: $v\r\n"; } continue; } $head_buffer .= "$key: $val\r\n"; } - return $head_buffer."\r\n"; + return $head_buffer . "\r\n"; } public function setHeader($key, $val) @@ -88,7 +81,7 @@ public function setHeader($key, $val) public function getHeader($name) { - return isset($this->_headers[$name]) ? $this->_headers[$name] : ''; + return $this->_headers[$name] ?? ''; } public function removeHeader($name) @@ -98,43 +91,35 @@ public function removeHeader($name) public function write($chunk) { - if(!isset($this->_headers['Content-Length'])) - { + if (! isset($this->_headers['Content-Length'])) { $chunk = dechex(strlen($chunk)) . "\r\n" . $chunk . "\r\n"; } - if(!$this->headersSent) - { + if (! $this->headersSent) { $head_buffer = $this->getHeadBuffer(); $this->_buffer = $head_buffer . $chunk; $this->headersSent = true; - } - else - { + } else { $this->_buffer .= $chunk; } } - + public function end($data = null) { - if(!$this->writable) - { - echo new \Exception('unwirtable'); + if (! $this->writable) { + echo new Exception('unwirtable'); return false; } - if($data !== null) - { + if ($data !== null) { $this->write($data); } - - if(!$this->headersSent) - { + + if (! $this->headersSent) { $head_buffer = $this->getHeadBuffer(); $this->_buffer = $head_buffer; $this->headersSent = true; } - - if(!isset($this->_headers['Content-Length'])) - { + + if (! isset($this->_headers['Content-Length'])) { $ret = $this->_connection->send($this->_buffer . "0\r\n\r\n", true); $this->destroy(); return $ret; @@ -143,64 +128,62 @@ public function end($data = null) $this->destroy(); return $ret; } - + public function destroy() { - if(!empty($this->_connection->httpRequest)) - { + if (! empty($this->_connection->httpRequest)) { $this->_connection->httpRequest->destroy(); } - if(!empty($this->_connection)) - { + if (! empty($this->_connection)) { $this->_connection->httpResponse = $this->_connection->httpRequest = null; } $this->_connection = null; $this->writable = false; } - - public static $codes = array( - 100 => 'Continue', - 101 => 'Switching Protocols', - 200 => 'OK', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 306 => '(Unused)', - 307 => 'Temporary Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - ); + + public static $codes = [ + 100 => 'Continue', + 101 => 'Switching Protocols', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 306 => '(Unused)', + 307 => 'Temporary Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + 422 => 'Unprocessable Entity', + 423 => 'Locked', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + ]; } diff --git a/src/Engine/Protocols/SocketIO.php b/src/Engine/Protocols/SocketIO.php index 054b0c5..0773560 100644 --- a/src/Engine/Protocols/SocketIO.php +++ b/src/Engine/Protocols/SocketIO.php @@ -1,22 +1,23 @@ hasReadedHead)) - { + if (! empty($connection->hasReadedHead)) { return strlen($http_buffer); } - $pos = strpos($http_buffer, "\r\n\r\n"); - if(!$pos) - { - if(strlen($http_buffer) >= $connection->maxPackageSize) - { + $pos = strpos($http_buffer, "\r\n\r\n"); + if (! $pos) { + if (strlen($http_buffer) >= $connection->maxPackageSize) { $connection->close("HTTP/1.1 400 bad request\r\n\r\nheader too long"); return 0; } @@ -32,99 +33,76 @@ public static function input($http_buffer, $connection) $connection->hasReadedHead = true; TcpConnection::$statistics['total_request']++; $connection->onClose = '\PHPSocketIO\Engine\Protocols\SocketIO::emitClose'; - if(isset($req->headers['upgrade']) && strtolower($req->headers['upgrade']) === 'websocket') - { + if (isset($req->headers['upgrade']) && strtolower($req->headers['upgrade']) === 'websocket') { $connection->consumeRecvBuffer(strlen($http_buffer)); WebSocket::dealHandshake($connection, $req, $res); self::cleanup($connection); return 0; } - if(!empty($connection->onRequest)) - { + if (! empty($connection->onRequest)) { $connection->consumeRecvBuffer(strlen($http_buffer)); self::emitRequest($connection, $req, $res); - if($req->method === 'GET' || $req->method === 'OPTIONS') - { + if ($req->method === 'GET' || $req->method === 'OPTIONS') { self::emitEnd($connection, $req); return 0; } // POST - if('\PHPSocketIO\Engine\Protocols\SocketIO::onData' !== $connection->onMessage) - { + if ('\PHPSocketIO\Engine\Protocols\SocketIO::onData' !== $connection->onMessage) { $connection->onMessage = '\PHPSocketIO\Engine\Protocols\SocketIO::onData'; } - if(!$raw_body) - { + if (! $raw_body) { return 0; } self::onData($connection, $raw_body); return 0; - } - else - { - if($req->method === 'GET') - { + } else { + if ($req->method === 'GET') { return $pos + 4; - } - elseif(isset($req->headers['content-length'])) - { + } elseif (isset($req->headers['content-length'])) { return $req->headers['content-length']; - } - else - { + } else { $connection->close("HTTP/1.1 400 bad request\r\n\r\ntrunk not support"); - return 0; + return 0; } } } - + public static function onData($connection, $data) { $req = $connection->httpRequest; self::emitData($connection, $req, $data); - if((isset($req->headers['content-length']) && $req->headers['content-length'] <= strlen($data)) - || substr($data, -5) === "0\r\n\r\n") - { + if ((isset($req->headers['content-length']) && $req->headers['content-length'] <= strlen($data)) + || substr($data, -5) === "0\r\n\r\n" + ) { self::emitEnd($connection, $req); } } protected static function emitRequest($connection, $req, $res) { - try - { + try { call_user_func($connection->onRequest, $req, $res); - } - catch(\Exception $e) - { + } catch (Exception $e) { echo $e; } } - + public static function emitClose($connection) { $req = $connection->httpRequest; - if(isset($req->onClose)) - { - try - { + if (isset($req->onClose)) { + try { call_user_func($req->onClose, $req); - } - catch(\Exception $e) - { + } catch (Exception $e) { echo $e; } } $res = $connection->httpResponse; - if(isset($res->onClose)) - { - try - { + if (isset($res->onClose)) { + try { call_user_func($res->onClose, $res); - } - catch(\Exception $e) - { + } catch (Exception $e) { echo $e; } } @@ -133,51 +111,39 @@ public static function emitClose($connection) public static function cleanup($connection) { - if(!empty($connection->onRequest)) - { + if (! empty($connection->onRequest)) { $connection->onRequest = null; } - if(!empty($connection->onWebSocketConnect)) - { + if (! empty($connection->onWebSocketConnect)) { $connection->onWebSocketConnect = null; } - if(!empty($connection->httpRequest)) - { + if (! empty($connection->httpRequest)) { $connection->httpRequest->destroy(); $connection->httpRequest = null; } - if(!empty($connection->httpResponse)) - { + if (! empty($connection->httpResponse)) { $connection->httpResponse->destroy(); $connection->httpResponse = null; } } - + public static function emitData($connection, $req, $data) { - if(isset($req->onData)) - { - try - { + if (isset($req->onData)) { + try { call_user_func($req->onData, $req, $data); - } - catch(\Exception $e) - { + } catch (Exception $e) { echo $e; } } - } - + } + public static function emitEnd($connection, $req) { - if(isset($req->onEnd)) - { - try - { + if (isset($req->onEnd)) { + try { call_user_func($req->onEnd, $req); - } - catch(\Exception $e) - { + } catch (Exception $e) { echo $e; } } @@ -186,8 +152,7 @@ public static function emitEnd($connection, $req) public static function encode($buffer, $connection) { - if(!isset($connection->onRequest)) - { + if (! isset($connection->onRequest)) { $connection->httpResponse->setHeader('Content-Length', strlen($buffer)); return $connection->httpResponse->getHeadBuffer() . $buffer; } @@ -196,12 +161,9 @@ public static function encode($buffer, $connection) public static function decode($http_buffer, $connection) { - if(isset($connection->onRequest)) - { + if (isset($connection->onRequest)) { return $http_buffer; - } - else - { + } else { list($head, $body) = explode("\r\n\r\n", $http_buffer, 2); return $body; } diff --git a/src/Engine/Protocols/WebSocket.php b/src/Engine/Protocols/WebSocket.php index 6a4dcf5..6c7883a 100644 --- a/src/Engine/Protocols/WebSocket.php +++ b/src/Engine/Protocols/WebSocket.php @@ -1,4 +1,4 @@ - + * @author walkor * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + namespace PHPSocketIO\Engine\Protocols; use \PHPSocketIO\Engine\Protocols\Http\Request; @@ -25,34 +26,32 @@ class WebSocket { /** * 最小包头 + * * @var int */ const MIN_HEAD_LEN = 7; - + /** * 检查包的完整性 + * * @param string $buffer */ public static function input($buffer, $connection) { - if(strlen($buffer) < self::MIN_HEAD_LEN) - { + if (strlen($buffer) < self::MIN_HEAD_LEN) { return 0; } // flash policy file - if(0 === strpos($buffer,'send($policy_xml, true); $connection->consumeRecvBuffer(strlen($buffer)); return 0; } // http head $pos = strpos($buffer, "\r\n\r\n"); - if(!$pos) - { - if(strlen($buffer)>=TcpConnection::$maxPackageSize) - { + if (! $pos) { + if (strlen($buffer) >= TcpConnection::$maxPackageSize) { $connection->close("HTTP/1.1 400 bad request\r\n\r\nheader too long"); return 0; } @@ -62,20 +61,20 @@ public static function input($buffer, $connection) $res = new Response($connection); $connection->consumeRecvBuffer(strlen($buffer)); return self::dealHandshake($connection, $req, $res); - $connection->consumeRecvBuffer($pos+4); + $connection->consumeRecvBuffer($pos + 4); return 0; } /** * 处理websocket握手 - * @param string $buffer - * @param TcpConnection $connection + * + * @param string $buffer + * @param TcpConnection $connection * @return int */ public static function dealHandshake($connection, $req, $res) { - if(isset($req->headers['sec-websocket-key1'])) - { + if (isset($req->headers['sec-websocket-key1'])) { $res->writeHead(400); $res->end("Not support"); return 0; diff --git a/src/Engine/Protocols/WebSocket/RFC6455.php b/src/Engine/Protocols/WebSocket/RFC6455.php index afca7d2..8e39454 100644 --- a/src/Engine/Protocols/WebSocket/RFC6455.php +++ b/src/Engine/Protocols/WebSocket/RFC6455.php @@ -7,41 +7,46 @@ * For full copyright and license information, please see the MIT-LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @author walkor + * @author walkor * @copyright walkor - * @link http://www.workerman.net/ - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License */ namespace PHPSocketIO\Engine\Protocols\WebSocket; use Workerman\Connection\ConnectionInterface; +use Workerman\Protocols\ProtocolInterface; /** * WebSocket 协议服务端解包和打包 */ -class RFC6455 implements \Workerman\Protocols\ProtocolInterface +class RFC6455 implements ProtocolInterface { /** * websocket头部最小长度 + * * @var int */ const MIN_HEAD_LEN = 6; /** * websocket blob类型 + * * @var char */ const BINARY_TYPE_BLOB = "\x81"; /** * websocket arraybuffer类型 + * * @var char */ const BINARY_TYPE_ARRAYBUFFER = "\x82"; /** * 检查包的完整性 + * * @param string $buffer */ public static function input($buffer, ConnectionInterface $connection) @@ -66,55 +71,53 @@ public static function input($buffer, ConnectionInterface $connection) $is_fin_frame = $firstbyte >> 7; $opcode = $firstbyte & 0xf; switch ($opcode) { - // 附加数据帧 @todo 实现附加数据帧 + // 附加数据帧 @todo 实现附加数据帧 case 0x0: break; - // 文本数据帧 + // 文本数据帧 case 0x1: break; - // 二进制数据帧 + // 二进制数据帧 case 0x2: break; - // 关闭的包 + // 关闭的包 case 0x8: // 如果有设置onWebSocketClose回调,尝试执行 if (isset($connection->onWebSocketClose)) { call_user_func($connection->onWebSocketClose, $connection); - } - // 默认行为是关闭连接 + } // 默认行为是关闭连接 else { $connection->close(); } return 0; - // ping的包 + // ping的包 case 0x9: // 如果有设置onWebSocketPing回调,尝试执行 if (isset($connection->onWebSocketPing)) { call_user_func($connection->onWebSocketPing, $connection); - } - // 默认发送pong + } // 默认发送pong else { $connection->send(pack('H*', '8a00'), true); } // 从接受缓冲区中消费掉该数据包 - if (!$data_len) { + if (! $data_len) { $connection->consumeRecvBuffer(self::MIN_HEAD_LEN); return 0; } break; - // pong的包 + // pong的包 case 0xa: // 如果有设置onWebSocketPong回调,尝试执行 if (isset($connection->onWebSocketPong)) { call_user_func($connection->onWebSocketPong, $connection); } // 从接受缓冲区中消费掉该数据包 - if (!$data_len) { + if (! $data_len) { $connection->consumeRecvBuffer(self::MIN_HEAD_LEN); return 0; } break; - // 错误的opcode + // 错误的opcode default: echo "error opcode $opcode and close websocket connection\n"; $connection->close(); @@ -130,7 +133,7 @@ public static function input($buffer, ConnectionInterface $connection) } $pack = unpack('ntotal_len', substr($buffer, 2, 2)); $data_len = $pack['total_len']; - } else if ($data_len === 127) { + } elseif ($data_len === 127) { $head_len = 14; if ($head_len > $recv_len) { return 0; @@ -152,8 +155,7 @@ public static function input($buffer, ConnectionInterface $connection) $connection->consumeRecvBuffer($connection->websocketCurrentFrameLength); $connection->websocketCurrentFrameLength = 0; return 0; - } - // 收到的数据大于一个frame + } // 收到的数据大于一个frame elseif ($connection->websocketCurrentFrameLength < $recv_len) { self::decode(substr($buffer, 0, $connection->websocketCurrentFrameLength), $connection); $connection->consumeRecvBuffer($connection->websocketCurrentFrameLength); @@ -161,8 +163,7 @@ public static function input($buffer, ConnectionInterface $connection) $connection->websocketCurrentFrameLength = 0; // 继续读取下一个frame return self::input(substr($buffer, $current_frame_length), $connection); - } - // 收到的数据不足一个frame + } // 收到的数据不足一个frame else { return 0; } @@ -170,7 +171,8 @@ public static function input($buffer, ConnectionInterface $connection) /** * 打包 - * @param string $buffer + * + * @param string $buffer * @return string */ public static function encode($buffer, ConnectionInterface $connection) @@ -185,7 +187,7 @@ public static function encode($buffer, ConnectionInterface $connection) if ($len <= 125) { $encode_buffer = $first_byte . chr($len) . $buffer; - } else if ($len <= 65535) { + } elseif ($len <= 65535) { $encode_buffer = $first_byte . chr(126) . pack("n", $len) . $buffer; } else { $encode_buffer = $first_byte . chr(127) . pack("xxxxN", $len) . $buffer; @@ -207,7 +209,8 @@ public static function encode($buffer, ConnectionInterface $connection) /** * 解包 - * @param string $buffer + * + * @param string $buffer * @return string */ public static function decode($buffer, ConnectionInterface $connection) @@ -217,7 +220,7 @@ public static function decode($buffer, ConnectionInterface $connection) if ($len === 126) { $masks = substr($buffer, 4, 4); $data = substr($buffer, 8); - } else if ($len === 127) { + } elseif ($len === 127) { $masks = substr($buffer, 10, 4); $data = substr($buffer, 14); } else { @@ -239,20 +242,21 @@ public static function decode($buffer, ConnectionInterface $connection) /** * 处理websocket握手 - * @param string $buffer - * @param TcpConnection $connection + * + * @param string $buffer + * @param TcpConnection $connection * @return int */ public static function dealHandshake($connection, $req, $res) { - $headers = array(); + $headers = []; if (isset($connection->onWebSocketConnect)) { try { - call_user_func_array($connection->onWebSocketConnect, array($connection, $req, $res)); + call_user_func_array($connection->onWebSocketConnect, [$connection, $req, $res]); } catch (\Exception $e) { echo $e; } - if (!$res->writable) { + if (! $res->writable) { return false; } } @@ -286,7 +290,7 @@ public static function dealHandshake($connection, $req, $res) $res->end(); // 握手后有数据要发送 - if (!empty($connection->websocketTmpData)) { + if (! empty($connection->websocketTmpData)) { $connection->send($connection->websocketTmpData, true); $connection->websocketTmpData = ''; } diff --git a/src/Engine/Socket.php b/src/Engine/Socket.php index 683617f..a1e8190 100644 --- a/src/Engine/Socket.php +++ b/src/Engine/Socket.php @@ -13,9 +13,9 @@ class Socket extends Emitter public $upgrading = false; public $upgraded = false; public $readyState = 'opening'; - public $writeBuffer = array(); - public $packetsFn = array(); - public $sentCallbackFn = array(); + public $writeBuffer = []; + public $packetsFn = []; + public $sentCallbackFn = []; public $request = null; public $remoteAddress = ''; public $checkIntervalTimer; @@ -43,15 +43,15 @@ public function maybeUpgrade($transport) $this->upgrading = true; $this->upgradeTimeoutTimer = Timer::add( $this->server->upgradeTimeout, - array($this, 'upgradeTimeoutCallback'), - array($transport), + [$this, 'upgradeTimeoutCallback'], + [$transport], false ); $this->upgradeTransport = $transport; - $transport->on('packet', array($this, 'onUpgradePacket')); - $transport->once('close', array($this, 'onUpgradeTransportClose')); - $transport->once('error', array($this, 'onUpgradeTransportError')); - $this->once('close', array($this, 'onUpgradeTransportClose')); + $transport->on('packet', [$this, 'onUpgradePacket']); + $transport->once('close', [$this, 'onUpgradeTransportClose']); + $transport->once('error', [$this, 'onUpgradeTransportError']); + $this->once('close', [$this, 'onUpgradeTransportClose']); } public function onUpgradePacket($packet) @@ -61,13 +61,13 @@ public function onUpgradePacket($packet) return; } if ('ping' === $packet['type'] && (isset($packet['data']) && 'probe' === $packet['data'])) { - $this->upgradeTransport->send(array(array('type' => 'pong', 'data' => 'probe'))); + $this->upgradeTransport->send([['type' => 'pong', 'data' => 'probe']]); //$this->transport->shouldClose = function(){}; if ($this->checkIntervalTimer) { Timer::del($this->checkIntervalTimer); } - $this->checkIntervalTimer = Timer::add(0.5, array($this, 'check')); - } else if ('upgrade' === $packet['type'] && $this->readyState !== 'closed') { + $this->checkIntervalTimer = Timer::add(0.5, [$this, 'check']); + } elseif ('upgrade' === $packet['type'] && $this->readyState !== 'closed') { $this->upgradeCleanup(); $this->upgraded = true; $this->clearTransport(); @@ -78,10 +78,10 @@ public function onUpgradePacket($packet) $this->setPingTimeout(); $this->flush(); if ($this->readyState === 'closing') { - $this->transport->close(array($this, 'onClose')); + $this->transport->close([$this, 'onClose']); } } else { - if (!empty($this->upgradeTransport)) { + if (! empty($this->upgradeTransport)) { $this->upgradeCleanup(); $this->upgradeTransport->close(); $this->upgradeTransport = null; @@ -95,12 +95,12 @@ public function upgradeCleanup() $this->upgrading = false; Timer::del($this->checkIntervalTimer); Timer::del($this->upgradeTimeoutTimer); - if (!empty($this->upgradeTransport)) { - $this->upgradeTransport->removeListener('packet', array($this, 'onUpgradePacket')); - $this->upgradeTransport->removeListener('close', array($this, 'onUpgradeTransportClose')); - $this->upgradeTransport->removeListener('error', array($this, 'onUpgradeTransportError')); + if (! empty($this->upgradeTransport)) { + $this->upgradeTransport->removeListener('packet', [$this, 'onUpgradePacket']); + $this->upgradeTransport->removeListener('close', [$this, 'onUpgradeTransportClose']); + $this->upgradeTransport->removeListener('error', [$this, 'onUpgradeTransportError']); } - $this->removeListener('close', array($this, 'onUpgradeTransportClose')); + $this->removeListener('close', [$this, 'onUpgradeTransportClose']); } public function onUpgradeTransportClose() @@ -130,10 +130,10 @@ public function upgradeTimeoutCallback($transport) public function setTransport($transport) { $this->transport = $transport; - $this->transport->once('error', array($this, 'onError')); - $this->transport->on('packet', array($this, 'onPacket')); - $this->transport->on('drain', array($this, 'flush')); - $this->transport->once('close', array($this, 'onClose')); + $this->transport->once('error', [$this, 'onError']); + $this->transport->on('packet', [$this, 'onPacket']); + $this->transport->on('drain', [$this, 'flush']); + $this->transport->once('close', [$this, 'onClose']); //this function will manage packet events (also message callbacks) $this->setupSendCallback(); } @@ -144,9 +144,17 @@ public function onOpen() // sends an `open` packet $this->transport->sid = $this->id; - $this->sendPacket('open', json_encode(array( - 'sid' => $this->id, 'upgrades' => $this->getAvailableUpgrades(), 'pingInterval' => $this->server->pingInterval * 1000, 'pingTimeout' => $this->server->pingTimeout * 1000 - ))); + $this->sendPacket( + 'open', + json_encode( + [ + 'sid' => $this->id, + 'upgrades' => $this->getAvailableUpgrades(), + 'pingInterval' => $this->server->pingInterval * 1000, + 'pingTimeout' => $this->server->pingTimeout * 1000 + ] + ) + ); $this->emit('open'); $this->setPingTimeout(); @@ -162,7 +170,6 @@ public function onPacket($packet) // other side's liveness $this->setPingTimeout(); switch ($packet['type']) { - case 'ping': $this->sendPacket('pong'); $this->emit('heartbeat'); @@ -178,14 +185,14 @@ public function onPacket($packet) break; } } else { - echo ('packet received with closed socket'); + echo('packet received with closed socket'); } } public function check() { if ('polling' == $this->transport->name && $this->transport->writable) { - $this->transport->send(array(array('type' => 'noop'))); + $this->transport->send([['type' => 'noop']]); } } @@ -201,7 +208,7 @@ public function setPingTimeout() } $this->pingTimeoutTimer = Timer::add( $this->server->pingInterval + $this->server->pingTimeout, - array($this, 'pingTimeoutCallback'), + [$this, 'pingTimeoutCallback'], null, false ); @@ -225,19 +232,21 @@ public function onClose($reason = '', $description = null) if ('closed' !== $this->readyState) { Timer::del($this->pingTimeoutTimer); - if (!empty($this->checkIntervalTimer)) + if (! empty($this->checkIntervalTimer)) { Timer::del($this->checkIntervalTimer); + } $this->checkIntervalTimer = null; - if (!empty($this->checkIntervalTimer)) + if (! empty($this->checkIntervalTimer)) { Timer::del($this->upgradeTimeoutTimer); + } // clean writeBuffer in next tick, so developers can still // grab the writeBuffer on 'close' event - $this->writeBuffer = array(); - $this->packetsFn = array(); - $this->sentCallbackFn = array(); + $this->writeBuffer = []; + $this->packetsFn = []; + $this->sentCallbackFn = []; $this->clearTransport(); $this->readyState = 'closed'; $this->emit('close', $this->id, $reason, $description); @@ -245,7 +254,7 @@ public function onClose($reason = '', $description = null) $this->request = null; $this->upgradeTransport = null; $this->removeAllListeners(); - if (!empty($this->transport)) { + if (! empty($this->transport)) { $this->transport->removeAllListeners(); $this->transport = null; } @@ -258,7 +267,7 @@ public function send($data, $options, $callback) return $this; } - public function write($data, $options = array(), $callback = null) + public function write($data, $options = [], $callback = null) { return $this->send($data, $options, $callback); } @@ -266,9 +275,9 @@ public function write($data, $options = array(), $callback = null) public function sendPacket($type, $data = null, $callback = null) { if ('closing' !== $this->readyState) { - $packet = array( + $packet = [ 'type' => $type - ); + ]; if ($data !== null) { $packet['data'] = $data; } @@ -285,23 +294,22 @@ public function sendPacket($type, $data = null, $callback = null) public function flush() { - if ( - 'closed' !== $this->readyState && $this->transport->writable + if ('closed' !== $this->readyState && $this->transport->writable && $this->writeBuffer ) { $this->emit('flush', $this->writeBuffer); $this->server->emit('flush', $this, $this->writeBuffer); $wbuf = $this->writeBuffer; - $this->writeBuffer = array(); + $this->writeBuffer = []; if ($this->packetsFn) { - if (!empty($this->transport->supportsFraming)) { + if (! empty($this->transport->supportsFraming)) { $this->sentCallbackFn[] = $this->packetsFn; } else { // @todo check $this->sentCallbackFn[] = $this->packetsFn; } } - $this->packetsFn = array(); + $this->packetsFn = []; $this->transport->send($wbuf); $this->emit('drain'); if ($this->server) { @@ -312,7 +320,7 @@ public function flush() public function getAvailableUpgrades() { - return array('websocket'); + return ['websocket']; } public function close() @@ -324,7 +332,7 @@ public function close() $this->readyState = 'closing'; if ($this->writeBuffer) { - $this->once('drain', array($this, 'closeTransport')); + $this->once('drain', [$this, 'closeTransport']); return; } @@ -334,14 +342,14 @@ public function close() public function closeTransport() { //todo onClose.bind(this, 'forced close')); - $this->transport->close(array($this, 'onClose')); + $this->transport->close([$this, 'onClose']); } public function setupSendCallback() { $self = $this; //the message was sent successfully, execute the callback - $this->transport->on('drain', array($this, 'onDrainCallback')); + $this->transport->on('drain', [$this, 'onDrainCallback']); } public function onDrainCallback() @@ -349,10 +357,10 @@ public function onDrainCallback() if ($this->sentCallbackFn) { $seqFn = array_shift($this->sentCallbackFn); if (is_callable($seqFn)) { - echo ('executing send callback'); + echo('executing send callback'); call_user_func($seqFn, $this->transport); - } else if (is_array($seqFn)) { - echo ('executing batch send callback'); + } elseif (is_array($seqFn)) { + echo('executing batch send callback'); foreach ($seqFn as $fn) { call_user_func($fn, $this->transport); } diff --git a/src/Engine/Transport.php b/src/Engine/Transport.php index 0653f35..a027758 100644 --- a/src/Engine/Transport.php +++ b/src/Engine/Transport.php @@ -1,13 +1,16 @@ req = $req; } - + public function close($fn = null) { $this->readyState = 'closing'; - $fn = $fn ? $fn : array($this, 'noop'); + $fn = $fn ? $fn : [$this, 'noop']; $this->doClose($fn); } public function onError($msg, $desc = '') { - if ($this->listeners('error')) - { - $err = array( + if ($this->listeners('error')) { + $err = [ 'type' => 'TransportError', 'description' => $desc, - ); + ]; $this->emit('error', $err); - } - else - { + } else { echo("ignored transport error $msg $desc\n"); } } @@ -60,8 +59,8 @@ public function onData($data) { $this->onPacket(Parser::decodePacket($data)); } - - public function onClose() + + public function onClose() { $this->req = $this->res = null; $this->readyState = 'closed'; @@ -71,9 +70,9 @@ public function onClose() public function destroy() { - $this->req = $this->res = null; - $this->readyState = 'closed'; - $this->removeAllListeners(); - $this->shouldClose = null; + $this->req = $this->res = null; + $this->readyState = 'closed'; + $this->removeAllListeners(); + $this->shouldClose = null; } } diff --git a/src/Engine/Transports/Polling.php b/src/Engine/Transports/Polling.php index 8ad0dc5..5c6006b 100644 --- a/src/Engine/Transports/Polling.php +++ b/src/Engine/Transports/Polling.php @@ -1,38 +1,36 @@ res; - if ('GET' === $req->method) - { + if ('GET' === $req->method) { $this->onPollRequest($req, $res); - } - else if('POST' === $req->method) - { + } elseif ('POST' === $req->method) { $this->onDataRequest($req, $res); - } - else - { + } else { $res->writeHead(500); $res->end(); } } - public function onPollRequest($req, $res) + public function onPollRequest($req, $res) { - if($this->req) - { - echo ('request overlap'); + if ($this->req) { + echo('request overlap'); // assert: this.res, '.req and .res should be (un)set together' $this->onError('overlap from client'); $res->writeHead(500); @@ -42,18 +40,16 @@ public function onPollRequest($req, $res) $this->req = $req; $this->res = $res; - - $req->onClose = array($this, 'pollRequestOnClose'); - $req->cleanup = array($this, 'pollRequestClean'); + $req->onClose = [$this, 'pollRequestOnClose']; + $req->cleanup = [$this, 'pollRequestClean']; $this->writable = true; $this->emit('drain'); // if we're still writable but had a pending close, trigger an empty send - if ($this->writable && $this->shouldClose) - { + if ($this->writable && $this->shouldClose) { echo('triggering empty send to append close packet'); - $this->send(array(array('type'=>'noop'))); + $this->send([['type' => 'noop']]); } } @@ -62,21 +58,19 @@ public function pollRequestOnClose() $this->onError('poll connection closed prematurely'); $this->pollRequestClean(); } - + public function pollRequestClean() { - if(isset($this->req)) - { + if (isset($this->req)) { $this->req->res = null; $this->req->onClose = $this->req->cleanup = null; $this->req = $this->res = null; } } - public function onDataRequest($req, $res) + public function onDataRequest($req, $res) { - if(isset($this->dataReq)) - { + if (isset($this->dataReq)) { // assert: this.dataRes, '.dataReq and .dataRes should be (un)set together' $this->onError('data request overlap from client'); $res->writeHead(500); @@ -85,9 +79,9 @@ public function onDataRequest($req, $res) $this->dataReq = $req; $this->dataRes = $res; - $req->onClose = array($this, 'dataRequestOnClose'); - $req->onData = array($this, 'dataRequestOnData'); - $req->onEnd = array($this, 'dataRequestOnEnd'); + $req->onClose = [$this, 'dataRequestOnClose']; + $req->onData = [$this, 'dataRequestOnData']; + $req->onEnd = [$this, 'dataRequestOnEnd']; } public function dataRequestCleanup() @@ -115,60 +109,53 @@ public function dataRequestOnData($req, $data) }*/ } - public function dataRequestOnEnd () + public function dataRequestOnEnd() { $this->onData($this->chunks); - $headers = array( - 'Content-Type'=> 'text/html', - 'Content-Length'=> 2, - 'X-XSS-Protection' => '0', - ); + $headers = [ + 'Content-Type' => 'text/html', + 'Content-Length' => 2, + 'X-XSS-Protection' => '0', + ]; $this->dataRes->writeHead(200, '', $this->headers($this->dataReq, $headers)); $this->dataRes->end('ok'); $this->dataRequestCleanup(); } - + public function onData($data) { - $packets = Parser::decodePayload($data); - if(isset($packets['type'])) - { - if('close' === $packets['type']) - { - $this->onClose(); - return false; - } - else - { - $packets = array($packets); - } - } - - foreach($packets as $packet) - { - $this->onPacket($packet); - } + $packets = Parser::decodePayload($data); + if (isset($packets['type'])) { + if ('close' === $packets['type']) { + $this->onClose(); + return false; + } else { + $packets = [$packets]; + } + } + + foreach ($packets as $packet) { + $this->onPacket($packet); + } } - + public function onClose() { - if($this->writable) - { - // close pending poll request - $this->send(array(array('type'=> 'noop'))); - } - parent::onClose(); + if ($this->writable) { + // close pending poll request + $this->send([['type' => 'noop']]); + } + parent::onClose(); } - public function send($packets) - { + public function send($packets) + { $this->writable = false; - if($this->shouldClose) - { + if ($this->shouldClose) { echo('appending close packet to payload'); - $packets[] = array('type'=>'close'); + $packets[] = ['type' => 'close']; call_user_func($this->shouldClose); $this->shouldClose = null; } @@ -176,33 +163,28 @@ public function send($packets) $this->write($data); } - public function write($data) + public function write($data) { $this->doWrite($data); - if(!empty($this->req->cleanup)) - { + if (! empty($this->req->cleanup)) { call_user_func($this->req->cleanup); } } - public function doClose($fn) + public function doClose($fn) { - if(!empty($this->dataReq)) - { - //echo('aborting ongoing data request'); - $this->dataReq->destroy(); - } - - if($this->writable) - { - //echo('transport writable - closing right away'); - $this->send(array(array('type'=> 'close'))); - call_user_func($fn); - } - else - { - //echo("transport not writable - buffering orderly close\n"); - $this->shouldClose = $fn; - } + if (! empty($this->dataReq)) { + //echo('aborting ongoing data request'); + $this->dataReq->destroy(); + } + + if ($this->writable) { + //echo('transport writable - closing right away'); + $this->send([['type' => 'close']]); + call_user_func($fn); + } else { + //echo("transport not writable - buffering orderly close\n"); + $this->shouldClose = $fn; + } } } diff --git a/src/Engine/Transports/PollingJsonp.php b/src/Engine/Transports/PollingJsonp.php index 024c073..58873ef 100644 --- a/src/Engine/Transports/PollingJsonp.php +++ b/src/Engine/Transports/PollingJsonp.php @@ -1,6 +1,9 @@ head = "___eio[ $j ]("; Debug::debug('PollingJsonp __construct'); } -public function __destruct() -{ - Debug::debug('PollingJsonp __destruct'); -} + + public function __destruct() + { + Debug::debug('PollingJsonp __destruct'); + } + public function onData($data) { $parsed_data = null; @@ -27,7 +32,7 @@ public function onData($data) /*data = data.replace(rSlashes, function(match, slashes) { return slashes ? match : '\n'; });*/ - call_user_func(array($this, 'parent::onData'), preg_replace('/\\\\n/', '\\n', $data)); + call_user_func([$this, 'parent::onData'], preg_replace('/\\\\n/', '\\n', $data)); } public function doWrite($data) @@ -39,25 +44,25 @@ public function doWrite($data) $data = $this->head . $js . $this->foot; // explicit UTF-8 is required for pages not served under utf - $headers = array( - 'Content-Type'=> 'text/javascript; charset=UTF-8', - 'Content-Length'=> strlen($data), - 'X-XSS-Protection'=>'0' - ); - if(empty($this->res)){echo new \Exception('empty $this->res');return;} - $this->res->writeHead(200, '',$this->headers($this->req, $headers)); + $headers = [ + 'Content-Type' => 'text/javascript; charset=UTF-8', + 'Content-Length' => strlen($data), + 'X-XSS-Protection' => '0' + ]; + if (empty($this->res)) { + echo new \Exception('empty $this->res'); + return; + } + $this->res->writeHead(200, '', $this->headers($this->req, $headers)); $this->res->end($data); } - - public function headers($req, $headers = array()) + + public function headers($req, $headers = []) { - $listeners = $this->listeners('headers'); - foreach($listeners as $listener) - { - $listener($headers); - } - return $headers; + $listeners = $this->listeners('headers'); + foreach ($listeners as $listener) { + $listener($headers); + } + return $headers; } - - } diff --git a/src/Engine/Transports/PollingXHR.php b/src/Engine/Transports/PollingXHR.php index 6148c96..21e8657 100644 --- a/src/Engine/Transports/PollingXHR.php +++ b/src/Engine/Transports/PollingXHR.php @@ -1,6 +1,9 @@ method) - { + if ('OPTIONS' === $req->method) { $res = $req->res; $headers = $this->headers($req); $headers['Access-Control-Allow-Headers'] = 'Content-Type'; $res->writeHead(200, '', $headers); $res->end(); - } - else - { + } else { parent::onRequest($req); } } @@ -37,34 +37,31 @@ public function doWrite($data) // : 'application/octet-stream'; $content_type = preg_match('/^\d+:/', $data) ? 'text/plain; charset=UTF-8' : 'application/octet-stream'; $content_length = strlen($data); - $headers = array( - 'Content-Type'=> $content_type, - 'Content-Length'=> $content_length, + $headers = [ + 'Content-Type' => $content_type, + 'Content-Length' => $content_length, 'X-XSS-Protection' => '0', - ); - if(empty($this->res)){echo new \Exception('empty this->res');return;} + ]; + if (empty($this->res)) { + echo new \Exception('empty this->res'); + return; + } $this->res->writeHead(200, '', $this->headers($this->req, $headers)); $this->res->end($data); } - - public function headers($req, $headers = array()) + + public function headers($req, $headers = []) { - if(isset($req->headers['origin'])) - { - $headers['Access-Control-Allow-Credentials'] = 'true'; - $headers['Access-Control-Allow-Origin'] = $req->headers['origin']; - } - else - { - $headers['Access-Control-Allow-Origin'] = '*'; - } - $listeners = $this->listeners('headers'); - foreach($listeners as $listener) - { - $listener($headers); - } - return $headers; + if (isset($req->headers['origin'])) { + $headers['Access-Control-Allow-Credentials'] = 'true'; + $headers['Access-Control-Allow-Origin'] = $req->headers['origin']; + } else { + $headers['Access-Control-Allow-Origin'] = '*'; + } + $listeners = $this->listeners('headers'); + foreach ($listeners as $listener) { + $listener($headers); + } + return $headers; } - - } diff --git a/src/Engine/Transports/WebSocket.php b/src/Engine/Transports/WebSocket.php index 23f4b97..3e6d087 100644 --- a/src/Engine/Transports/WebSocket.php +++ b/src/Engine/Transports/WebSocket.php @@ -1,40 +1,45 @@ socket = $req->connection; - $this->socket->onMessage = array($this, 'onData2'); - $this->socket->onClose = array($this, 'onClose'); - $this->socket->onError = array($this, 'onError2'); + $this->socket->onMessage = [$this, 'onData2']; + $this->socket->onClose = [$this, 'onClose']; + $this->socket->onError = [$this, 'onError2']; Debug::debug('WebSocket __construct'); } + public function __destruct() { Debug::debug('WebSocket __destruct'); } - public function onData2($connection, $data) + + public function onData2($connection, $data) { - call_user_func(array($this, 'parent::onData'), $data); + call_user_func([$this, 'parent::onData'], $data); } - + public function onError2($conection, $code, $msg) { - call_user_func(array($this, 'parent::onClose'), $code, $msg); + call_user_func([$this, 'parent::onClose'], $code, $msg); } - + public function send($packets) { - foreach($packets as $packet) - { + foreach ($packets as $packet) { $data = Parser::encodePacket($packet, $this->supportsBinary); if ($this->socket) { $this->socket->send($data); @@ -42,15 +47,13 @@ public function send($packets) } } } - - public function doClose($fn = null) + + public function doClose($fn = null) { - if($this->socket) - { + if ($this->socket) { $this->socket->close(); $this->socket = null; - if(!empty($fn)) - { + if (! empty($fn)) { call_user_func($fn); } } diff --git a/src/Event/Emitter.php b/src/Event/Emitter.php index 54f6e19..b519e7a 100644 --- a/src/Event/Emitter.php +++ b/src/Event/Emitter.php @@ -1,4 +1,5 @@ [[listener1, once?], [listener2,once?], ..], ..] */ - protected $_eventListenerMap = array(); - + protected $_eventListenerMap = []; + public function on($event_name, $listener) { $this->emit('newListener', $event_name, $listener); - $this->_eventListenerMap[$event_name][] = array($listener, 0); + $this->_eventListenerMap[$event_name][] = [$listener, 0]; return $this; } public function once($event_name, $listener) { - $this->_eventListenerMap[$event_name][] = array($listener, 1); + $this->_eventListenerMap[$event_name][] = [$listener, 1]; return $this; } - + public function removeListener($event_name, $listener) { - if(!isset($this->_eventListenerMap[$event_name])) - { + if (! isset($this->_eventListenerMap[$event_name])) { return $this; } - foreach($this->_eventListenerMap[$event_name] as $key=>$item) - { - if($item[0] === $listener) - { + foreach ($this->_eventListenerMap[$event_name] as $key => $item) { + if ($item[0] === $listener) { $this->emit('removeListener', $event_name, $listener); unset($this->_eventListenerMap[$event_name][$key]); } } - if(empty($this->_eventListenerMap[$event_name])) - { + if (empty($this->_eventListenerMap[$event_name])) { unset($this->_eventListenerMap[$event_name]); } return $this; @@ -57,9 +54,8 @@ public function removeListener($event_name, $listener) public function removeAllListeners($event_name = null) { $this->emit('removeListener', $event_name); - if(null === $event_name) - { - $this->_eventListenerMap = array(); + if (null === $event_name) { + $this->_eventListenerMap = []; return $this; } unset($this->_eventListenerMap[$event_name]); @@ -68,13 +64,11 @@ public function removeAllListeners($event_name = null) public function listeners($event_name) { - if(empty($this->_eventListenerMap[$event_name])) - { - return array(); + if (empty($this->_eventListenerMap[$event_name])) { + return []; } - $listeners = array(); - foreach($this->_eventListenerMap[$event_name] as $item) - { + $listeners = []; + foreach ($this->_eventListenerMap[$event_name] as $item) { $listeners[] = $item[0]; } return $listeners; @@ -82,26 +76,21 @@ public function listeners($event_name) public function emit($event_name = null) { - if(empty($event_name) || empty($this->_eventListenerMap[$event_name])) - { + if (empty($event_name) || empty($this->_eventListenerMap[$event_name])) { return false; } - foreach($this->_eventListenerMap[$event_name] as $key=>$item) - { - $args = func_get_args(); - unset($args[0]); - call_user_func_array($item[0], $args); - // once ? - if($item[1]) - { - unset($this->_eventListenerMap[$event_name][$key]); - if(empty($this->_eventListenerMap[$event_name])) - { - unset($this->_eventListenerMap[$event_name]); - } - } + foreach ($this->_eventListenerMap[$event_name] as $key => $item) { + $args = func_get_args(); + unset($args[0]); + call_user_func_array($item[0], $args); + // once ? + if ($item[1]) { + unset($this->_eventListenerMap[$event_name][$key]); + if (empty($this->_eventListenerMap[$event_name])) { + unset($this->_eventListenerMap[$event_name]); + } + } } return true; } - } diff --git a/src/Nsp.php b/src/Nsp.php index 045cd72..84f0ac5 100644 --- a/src/Nsp.php +++ b/src/Nsp.php @@ -1,33 +1,34 @@ 'connect', // for symmetry with client 'connection' => 'connection', 'newListener' => 'newListener' - ); - - //public static $flags = array('json','volatile'); + ]; public function __construct($server, $name) { - $this->name = $name; - $this->server = $server; - $this->initAdapter(); - Debug::debug('Nsp __construct'); + $this->name = $name; + $this->server = $server; + $this->initAdapter(); + Debug::debug('Nsp __construct'); } public function __destruct() @@ -43,8 +44,7 @@ public function initAdapter() public function to($name) { - if(!isset($this->rooms[$name])) - { + if (! isset($this->rooms[$name])) { $this->rooms[$name] = $name; } return $this; @@ -55,32 +55,28 @@ public function in($name) return $this->to($name); } - public function add($client, $nsp, $fn) { $socket_name = $this->server->socket(); $socket = new $socket_name($this, $client); - if('open' === $client->conn->readyState) - { - $this->sockets[$socket->id]=$socket; + if ('open' === $client->conn->readyState) { + $this->sockets[$socket->id] = $socket; $socket->onconnect(); - if(!empty($fn)) call_user_func($fn, $socket, $nsp); + if (! empty($fn)) { + call_user_func($fn, $socket, $nsp); + } $this->emit('connect', $socket); $this->emit('connection', $socket); - } - else - { + } else { echo('next called after client was closed - ignoring socket'); } } - /** * Removes a client. Called by each `Socket`. * * @api private */ - public function remove($socket) { // todo $socket->id @@ -92,38 +88,37 @@ public function remove($socket) * Emits to all clients. * * @return {Namespace} self - * @api public + * @api public */ - public function emit($ev = null) { $args = func_get_args(); - if (isset(self::$events[$ev])) - { - call_user_func_array(array(get_parent_class(__CLASS__), 'emit'), $args); - } - else - { + if (isset(self::$events[$ev])) { + call_user_func_array([get_parent_class(__CLASS__), 'emit'], $args); + } else { // set up packet object $parserType = Parser::EVENT; // default //if (self::hasBin($args)) { $parserType = Parser::BINARY_EVENT; } // binary - $packet = array('type'=> $parserType, 'data'=> $args ); + $packet = ['type' => $parserType, 'data' => $args]; - if (is_callable(end($args))) - { + if (is_callable(end($args))) { echo('Callbacks are not supported when broadcasting'); return; - } - - $this->adapter->broadcast($packet, array( - 'rooms'=> $this->rooms, - 'flags'=> $this->flags - )); - - $this->rooms = array(); - $this->flags = array();; + } + + $this->adapter->broadcast( + $packet, + [ + 'rooms' => $this->rooms, + 'flags' => $this->flags + ] + ); + + $this->rooms = []; + $this->flags = []; + ; } return $this; } @@ -139,7 +134,7 @@ public function send() public function write() { $args = func_get_args(); - return call_user_func_array(array($this, 'send'), $args); + return call_user_func_array([$this, 'send'], $args); } public function clients($fn) @@ -151,13 +146,12 @@ public function clients($fn) /** * Sets the compress flag. * - * @param {Boolean} if `true`, compresses the sending data + * @param {Boolean} if `true`, compresses the sending data * @return {Socket} self - * @api public + * @api public */ - - public function compress($compress) - { + public function compress($compress) + { $this->flags['compress'] = $compress; return $this; } diff --git a/src/Parser/Decoder.php b/src/Parser/Decoder.php index 06a4109..d58b98e 100644 --- a/src/Parser/Decoder.php +++ b/src/Parser/Decoder.php @@ -1,9 +1,13 @@ reconstructor = new BinaryReconstructor(packet); + if (is_string($obj)) { + $packet = self::decodeString($obj); + if (Parser::BINARY_EVENT == $packet['type'] || Parser::BINARY_ACK == $packet['type']) { + // binary packet's json todo BinaryReconstructor + $this->reconstructor = new BinaryReconstructor(packet); - // no attachments, labeled binary but no binary data to follow - if ($this->reconstructor->reconPack->attachments === 0) - { - $this->emit('decoded', $packet); - } - } else { // non-binary full packet - $this->emit('decoded', $packet); - } - } - else if (isBuf($obj) || !empty($obj['base64'])) - { // raw binary data - if (!$this->reconstructor) - { - throw new \Exception('got binary data when not reconstructing a packet'); + // no attachments, labeled binary but no binary data to follow + if ($this->reconstructor->reconPack->attachments === 0) { + $this->emit('decoded', $packet); + } + } else { // non-binary full packet + $this->emit('decoded', $packet); + } + } elseif (isBuf($obj) || ! empty($obj['base64'])) { // raw binary data + if (! $this->reconstructor) { + throw new Exception('got binary data when not reconstructing a packet'); } else { $packet = $this->reconstructor->takeBinaryData($obj); - if ($packet) - { // received final buffer + if ($packet) { // received final buffer $this->reconstructor = null; $this->emit('decoded', $packet); } } - } - else { - throw new \Exception('Unknown type: ' + obj); + } else { + throw new Exception('Unknown type: ' + obj); } } - public function decodeString($str) + public function decodeString($str) { - $p = array(); + $p = []; $i = 0; // look up type $p['type'] = $str[0]; - if(!isset(Parser::$types[$p['type']])) return self::error(); + if (! isset(Parser::$types[$p['type']])) { + return self::error(); + } // look up attachments if type binary - if(Parser::BINARY_EVENT == $p['type'] || Parser::BINARY_ACK == $p['type']) - { + if (Parser::BINARY_EVENT == $p['type'] || Parser::BINARY_ACK == $p['type']) { $buf = ''; - while ($str[++$i] != '-') - { + while ($str[++$i] != '-') { $buf .= $str[$i]; - if($i == strlen(str)) break; + if ($i == strlen(str)) { + break; + } } - if ($buf != intval($buf) || $str[$i] != '-') - { - throw new \Exception('Illegal attachments'); + if ($buf != intval($buf) || $str[$i] != '-') { + throw new Exception('Illegal attachments'); } $p['attachments'] = intval($buf); } // look up namespace (if any) - if(isset($str[$i + 1]) && '/' === $str[$i + 1]) - { + if (isset($str[$i + 1]) && '/' === $str[$i + 1]) { $p['nsp'] = ''; - while (++$i) - { - if ($i === strlen($str)) break; + while (++$i) { + if ($i === strlen($str)) { + break; + } $c = $str[$i]; - if (',' === $c) break; + if (',' === $c) { + break; + } $p['nsp'] .= $c; } } else { @@ -94,47 +93,43 @@ public function decodeString($str) } // look up id - if(isset($str[$i+1])) - { - $next = $str[$i+1]; - if ('' !== $next && strval((int)$next) === strval($next)) - { + if (isset($str[$i + 1])) { + $next = $str[$i + 1]; + if ('' !== $next && strval((int)$next) === strval($next)) { $p['id'] = ''; - while (++$i) - { + while (++$i) { $c = $str[$i]; - if (null == $c || strval((int)$c) != strval($c)) - { + if (null == $c || strval((int)$c) != strval($c)) { --$i; break; } $p['id'] .= $str[$i]; - if($i == strlen($str)) break; + if ($i == strlen($str)) { + break; + } } $p['id'] = (int)$p['id']; } } // look up json data - if (isset($str[++$i])) - { + if (isset($str[++$i])) { // todo try $p['data'] = json_decode(substr($str, $i), true); } return $p; } - + public static function error() { - return array( - 'type'=> Parser::ERROR, - 'data'=> 'parser error' - ); + return [ + 'type' => Parser::ERROR, + 'data' => 'parser error' + ]; } public function destroy() { - } } diff --git a/src/Parser/Encoder.php b/src/Parser/Encoder.php index 87a57fe..8252f8d 100644 --- a/src/Parser/Encoder.php +++ b/src/Parser/Encoder.php @@ -1,9 +1,12 @@ 'error', + public static $events = [ + 'error' => 'error', 'connect' => 'connect', 'disconnect' => 'disconnect', 'newListener' => 'newListener', 'removeListener' => 'removeListener' - ); + ]; - public static $flagsMap = array( + public static $flagsMap = [ 'json' => 'json', 'volatile' => 'volatile', 'broadcast' => 'broadcast' - ); + ]; public function __construct($nsp, $client) { $this->nsp = $nsp; $this->server = $nsp->server; $this->adapter = $this->nsp->adapter; - $this->id = ($nsp->name !== '/') ? $nsp->name .'#' .$client->id : $client->id; + $this->id = ($nsp->name !== '/') ? $nsp->name . '#' . $client->id : $client->id; $this->request = $client->request; $this->client = $client; $this->conn = $client->conn; @@ -54,78 +58,74 @@ public function __destruct() public function buildHandshake() { //todo check this->request->_query - $info = !empty($this->request->url) ? parse_url($this->request->url) : array(); - $query = array(); - if(isset($info['query'])) - { + $info = ! empty($this->request->url) ? parse_url($this->request->url) : []; + $query = []; + if (isset($info['query'])) { parse_str($info['query'], $query); } - return array( - 'headers' => isset($this->request->headers) ? $this->request->headers : array(), - 'time'=> date('D M d Y H:i:s') . ' GMT', - 'address'=> $this->conn->remoteAddress, - 'xdomain'=> isset($this->request->headers['origin']), - 'secure' => !empty($this->request->connection->encrypted), + return [ + 'headers' => $this->request->headers ?? [], + 'time' => date('D M d Y H:i:s') . ' GMT', + 'address' => $this->conn->remoteAddress, + 'xdomain' => isset($this->request->headers['origin']), + 'secure' => ! empty($this->request->connection->encrypted), 'issued' => time(), - 'url' => isset($this->request->url) ? $this->request->url : '', + 'url' => $this->request->url ?? '', 'query' => $query, - ); + ]; } public function __get($name) { - if($name === 'broadcast') - { + if ($name === 'broadcast') { $this->flags['broadcast'] = true; return $this; } return null; } + /** + * @throws Exception + */ public function emit($ev = null) { $args = func_get_args(); - if (isset(self::$events[$ev])) - { - call_user_func_array(array(__CLASS__, 'parent::emit'), $args); - } - else - { - $packet = array(); + if (isset(self::$events[$ev])) { + call_user_func_array([__CLASS__, 'parent::emit'], $args); + } else { + $packet = []; // todo check //$packet['type'] = hasBin($args) ? Parser::BINARY_EVENT : Parser::EVENT; $packet['type'] = Parser::EVENT; $packet['data'] = $args; $flags = $this->flags; // access last argument to see if it's an ACK callback - if (is_callable(end($args))) - { - if ($this->_rooms || isset($flags['broadcast'])) - { - throw new \Exception('Callbacks are not supported when broadcasting'); + if (is_callable(end($args))) { + if ($this->_rooms || isset($flags['broadcast'])) { + throw new Exception('Callbacks are not supported when broadcasting'); } echo('emitting packet with ack id ' . $this->nsp->ids); $this->acks[$this->nsp->ids] = array_pop($args); $packet['id'] = $this->nsp->ids++; } - if ($this->_rooms || !empty($flags['broadcast'])) - { - $this->adapter->broadcast($packet, array( - 'except' => array($this->id => $this->id), - 'rooms'=> $this->_rooms, - 'flags' => $flags - )); - } - else - { + if ($this->_rooms || ! empty($flags['broadcast'])) { + $this->adapter->broadcast( + $packet, + [ + 'except' => [$this->id => $this->id], + 'rooms' => $this->_rooms, + 'flags' => $flags + ] + ); + } else { // dispatch packet $this->packet($packet); } // reset flags - $this->_rooms = array(); - $this->flags = array(); + $this->_rooms = []; + $this->flags = []; } return $this; } @@ -134,15 +134,13 @@ public function emit($ev = null) /** * Targets a room when broadcasting. * - * @param {String} name + * @param {String} name * @return {Socket} self - * @api public + * @api public */ - public function to($name) { - if(!isset($this->_rooms[$name])) - { + if (! isset($this->_rooms[$name])) { $this->_rooms[$name] = $name; } return $this; @@ -157,14 +155,13 @@ public function in($name) * Sends a `message` event. * * @return {Socket} self - * @api public + * @api public */ - public function send() { $args = func_get_args(); array_unshift($args, 'message'); - call_user_func_array(array($this, 'emit'), $args); + call_user_func_array([$this, 'emit'], $args); return $this; } @@ -172,7 +169,7 @@ public function write() { $args = func_get_args(); array_unshift($args, 'message'); - call_user_func_array(array($this, 'emit'), $args); + call_user_func_array([$this, 'emit'], $args); return $this; } @@ -181,12 +178,13 @@ public function write() * * @param {Object} packet object * @param {Object} options - * @api private + * @api private */ - public function packet($packet, $preEncoded = false) { - if (!$this->nsp || !$this->client) return; + if (! $this->nsp || ! $this->client) { + return; + } $packet['nsp'] = $this->nsp->name; //$volatile = !empty(self::$flagsMap['volatile']); $volatile = false; @@ -196,16 +194,19 @@ public function packet($packet, $preEncoded = false) /** * Joins a room. * - * @param {String} room - * @param {Function} optional, callback + * @param {String} room + * @param {Function} optional, callback * @return {Socket} self - * @api private + * @api private */ - - public function join($room) - { - if (!$this->connected) return $this; - if(isset($this->rooms[$room])) return $this; + public function join($room) + { + if (! $this->connected) { + return $this; + } + if (isset($this->rooms[$room])) { + return $this; + } $this->adapter->add($this->id, $room); $this->rooms[$room] = $room; return $this; @@ -214,12 +215,11 @@ public function join($room) /** * Leaves a room. * - * @param {String} room - * @param {Function} optional, callback + * @param {String} room + * @param {Function} optional, callback * @return {Socket} self - * @api private + * @api private */ - public function leave($room) { $this->adapter->del($this->id, $room); @@ -236,7 +236,7 @@ public function leave($room) public function leaveAll() { $this->adapter->delAll($this->id); - $this->rooms = array(); + $this->rooms = []; } /** @@ -245,47 +245,42 @@ public function leaveAll() * * @api private */ - public function onconnect() { $this->nsp->connected[$this->id] = $this; $this->join($this->id); - $this->packet(array( - 'type' => Parser::CONNECT) - ); + $this->packet( + [ + 'type' => Parser::CONNECT + ] + ); } /** * Called with each packet. Called by `Client`. * - * @param {Object} packet - * @api private + * @param {Object} packet + * @throws Exception + * @api private */ - public function onpacket($packet) { - switch ($packet['type']) - { + switch ($packet['type']) { case Parser::EVENT: $this->onevent($packet); break; - case Parser::BINARY_EVENT: $this->onevent($packet); break; - case Parser::ACK: $this->onack($packet); break; - case Parser::BINARY_ACK: $this->onack($packet); break; - case Parser::DISCONNECT: $this->ondisconnect(); break; - case Parser::ERROR: $this->emit('error', $packet['data']); } @@ -295,40 +290,41 @@ public function onpacket($packet) * Called upon event packet. * * @param {Object} packet object - * @api private + * @api private */ - public function onevent($packet) { - $args = isset($packet['data']) ? $packet['data'] : array(); - if (!empty($packet['id']) || (isset($packet['id']) && $packet['id'] === 0)) - { + $args = $packet['data'] ?? []; + if (! empty($packet['id']) || (isset($packet['id']) && $packet['id'] === 0)) { $args[] = $this->ack($packet['id']); } - call_user_func_array(array(__CLASS__, 'parent::emit'), $args); + call_user_func_array([__CLASS__, 'parent::emit'], $args); } /** * Produces an ack callback to emit with an event. * * @param {Number} packet id - * @api private + * @api private */ - public function ack($id) { $self = $this; $sent = false; - return function()use(&$sent, $id, $self){ + return function () use (&$sent, $id, $self) { // prevent double callbacks - if ($sent) return; + if ($sent) { + return; + } $args = func_get_args(); $type = $this->hasBin($args) ? Parser::BINARY_ACK : Parser::ACK; - $self->packet(array( - 'id' => $id, - 'type' => $type, - 'data' => $args - )); + $self->packet( + [ + 'id' => $id, + 'type' => $type, + 'data' => $args + ] + ); }; } @@ -341,12 +337,11 @@ public function ack($id) public function onack($packet) { $ack = $this->acks[$packet['id']]; - if (is_callable($ack)) - { + if (is_callable($ack)) { call_user_func($ack, $packet['data']); unset($this->acks[$packet['id']]); } else { - echo ('bad ack '. $packet['id']); + echo('bad ack ' . $packet['id']); } } @@ -355,7 +350,6 @@ public function onack($packet) * * @api private */ - public function ondisconnect() { //echo('got disconnect packet'); @@ -367,30 +361,26 @@ public function ondisconnect() * * @api private */ - public function onerror($err) { - if ($this->listeners('error')) - { + if ($this->listeners('error')) { $this->emit('error', $err); } - else - { - //echo('Missing error handler on `socket`.'); - } } /** * Called upon closing. Called by `Client`. * - * @param {String} reason - * @param {Error} optional error object - * @api private + * @param {String} reason + * @param {Error} optional error object + * @throws Exception + * @api private */ - - public function onclose($reason) - { - if (!$this->connected) return $this; + public function onclose($reason) + { + if (! $this->connected) { + return $this; + } $this->emit('disconnect', $reason); $this->leaveAll(); $this->nsp->remove($this); @@ -412,34 +402,38 @@ public function onclose($reason) * Produces an `error` packet. * * @param {Object} error object - * @api private + * @api private */ public function error($err) { - $this->packet(array( - 'type' => Parser::ERROR, 'data' => $err ) - ); + $this->packet( + [ + 'type' => Parser::ERROR, 'data' => $err + ] + ); } /** * Disconnects this client. * - * @param {Boolean} if `true`, closes the underlying connection + * @param {Boolean} if `true`, closes the underlying connection * @return {Socket} self - * @api public + * @api public */ - - public function disconnect( $close = false ) + public function disconnect($close = false) { - if (!$this->connected) return $this; - if ($close) - { + if (! $this->connected) { + return $this; + } + if ($close) { $this->client->disconnect(); } else { - $this->packet(array( - 'type'=> Parser::DISCONNECT - )); + $this->packet( + [ + 'type' => Parser::DISCONNECT + ] + ); $this->onclose('server namespace disconnect'); } return $this; @@ -448,25 +442,28 @@ public function disconnect( $close = false ) /** * Sets the compress flag. * - * @param {Boolean} if `true`, compresses the sending data + * @param {Boolean} if `true`, compresses the sending data * @return {Socket} self - * @api public + * @api public */ - public function compress($compress) { $this->flags['compress'] = $compress; return $this; } - protected function hasBin($args) { + protected function hasBin($args) + { $hasBin = false; - array_walk_recursive($args, function($item, $key) use ($hasBin) { - if (!ctype_print($item)) { - $hasBin = true; + array_walk_recursive( + $args, + function ($item, $key) use ($hasBin) { + if (! ctype_print($item)) { + $hasBin = true; + } } - }); + ); return $hasBin; } diff --git a/src/SocketIO.php b/src/SocketIO.php index e4da692..972b1fb 100644 --- a/src/SocketIO.php +++ b/src/SocketIO.php @@ -1,12 +1,15 @@ nsp($nsp); - $socket = isset($opts['socket']) ? $opts['socket'] : '\PHPSocketIO\Socket'; + $socket = $opts['socket'] ?? '\PHPSocketIO\Socket'; $this->socket($socket); - $adapter = isset($opts['adapter']) ? $opts['adapter'] : '\PHPSocketIO\DefaultAdapter'; + $adapter = $opts['adapter'] ?? '\PHPSocketIO\DefaultAdapter'; $this->adapter($adapter); - if(isset($opts['origins'])) - { + if (isset($opts['origins'])) { $this->origins($opts['origins']); } @@ -34,16 +36,14 @@ public function __construct($port = null, $opts = array()) $this->sockets = $this->of('/'); - if(!class_exists('Protocols\SocketIO')) - { + if (! class_exists('Protocols\SocketIO')) { class_alias('PHPSocketIO\Engine\Protocols\SocketIO', 'Protocols\SocketIO'); } - if($port) - { - $worker = new Worker('SocketIO://0.0.0.0:'.$port, $opts); + if ($port) { + $worker = new Worker('SocketIO://0.0.0.0:' . $port, $opts); $worker->name = 'PHPSocketIO'; - if(isset($opts['ssl'])) { + if (isset($opts['ssl'])) { $worker->transport = 'ssl'; } @@ -53,74 +53,78 @@ class_alias('PHPSocketIO\Engine\Protocols\SocketIO', 'Protocols\SocketIO'); public function nsp($v = null) { - if (empty($v)) return $this->_nsp; - $this->_nsp = $v; - return $this; + if (empty($v)) { + return $this->_nsp; + } + $this->_nsp = $v; + return $this; } public function socket($v = null) { - if (empty($v)) return $this->_socket; - $this->_socket = $v; - return $this; + if (empty($v)) { + return $this->_socket; + } + $this->_socket = $v; + return $this; } public function adapter($v = null) { - if (empty($v)) return $this->_adapter; - $this->_adapter = $v; - foreach($this->nsps as $nsp) - { - $nsp->initAdapter(); - } - return $this; + if (empty($v)) { + return $this->_adapter; + } + $this->_adapter = $v; + foreach ($this->nsps as $nsp) { + $nsp->initAdapter(); + } + return $this; } public function origins($v = null) { - if ($v === null) return $this->_origins; + if ($v === null) { + return $this->_origins; + } $this->_origins = $v; - if(isset($this->engine)) { + if (isset($this->engine)) { $this->engine->origins = $this->_origins; } return $this; } - public function attach($srv, $opts = array()) + public function attach($srv, $opts = []) { - $engine = new Engine(); - $this->eio = $engine->attach($srv, $opts); + $engine = new Engine(); + $this->eio = $engine->attach($srv, $opts); - // Export http server - $this->worker = $srv; + // Export http server + $this->worker = $srv; - // bind to engine events - $this->bind($engine); + // bind to engine events + $this->bind($engine); - return $this; + return $this; } public function bind($engine) { $this->engine = $engine; - $this->engine->on('connection', array($this, 'onConnection')); + $this->engine->on('connection', [$this, 'onConnection']); $this->engine->origins = $this->_origins; return $this; } public function of($name, $fn = null) { - if($name[0] !== '/') - { + if ($name[0] !== '/') { $name = "/$name"; } - if(empty($this->nsps[$name])) - { + if (empty($this->nsps[$name])) { $nsp_name = $this->nsp(); $this->nsps[$name] = new $nsp_name($this, $name); } - if ($fn) - { + if ($fn) { $this->nsps[$name]->on('connect', $fn); } return $this->nsps[$name]; @@ -138,36 +142,36 @@ public function on() $args = array_pad(func_get_args(), 2, null); if ($args[0] === 'workerStart') { - $this->worker->onWorkerStart = $args[1]; - } else if ($args[0] === 'workerStop') { - $this->worker->onWorkerStop = $args[1]; - } else if ($args[0] !== null) { - return call_user_func_array(array($this->sockets, 'on'), $args); + $this->worker->onWorkerStart = $args[1]; + } elseif ($args[0] === 'workerStop') { + $this->worker->onWorkerStop = $args[1]; + } elseif ($args[0] !== null) { + return call_user_func_array([$this->sockets, 'on'], $args); } } public function in() { - return call_user_func_array(array($this->sockets, 'in'), func_get_args()); + return call_user_func_array([$this->sockets, 'in'], func_get_args()); } public function to() { - return call_user_func_array(array($this->sockets, 'to'), func_get_args()); + return call_user_func_array([$this->sockets, 'to'], func_get_args()); } public function emit() { - return call_user_func_array(array($this->sockets, 'emit'), func_get_args()); + return call_user_func_array([$this->sockets, 'emit'], func_get_args()); } public function send() { - return call_user_func_array(array($this->sockets, 'send'), func_get_args()); + return call_user_func_array([$this->sockets, 'send'], func_get_args()); } public function write() { - return call_user_func_array(array($this->sockets, 'write'), func_get_args()); + return call_user_func_array([$this->sockets, 'write'], func_get_args()); } } From cfd0e14134b5777e71c97d079e2fb2a2caf333fe Mon Sep 17 00:00:00 2001 From: Marcos Marcolin Date: Mon, 17 Jul 2023 21:10:33 -0300 Subject: [PATCH 2/2] refactor: code improvements with php_codesniffer without affecting logic, part 1. --- phpcs.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpcs.xml b/phpcs.xml index 209dc87..0f0bb89 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -1,6 +1,6 @@ - IXC Soft Coding Standard + PHPSocket.io Coding Standard