init
- 框架初始化 - 安装插件 - 修复PHP8.4报错
This commit is contained in:
250
vendor/workerman/phpsocket.io/src/Client.php
vendored
Normal file
250
vendor/workerman/phpsocket.io/src/Client.php
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
<?php
|
||||
|
||||
namespace PHPSocketIO;
|
||||
|
||||
use Exception;
|
||||
use PHPSocketIO\Parser\Decoder;
|
||||
use PHPSocketIO\Parser\Encoder;
|
||||
use PHPSocketIO\Parser\Parser;
|
||||
|
||||
class Client
|
||||
{
|
||||
public $server = null;
|
||||
public $conn = null;
|
||||
public $encoder = null;
|
||||
public $decoder = null;
|
||||
public $id = null;
|
||||
public $request = null;
|
||||
public $nsps = [];
|
||||
public $connectBuffer = [];
|
||||
/**
|
||||
* @var array|mixed|null
|
||||
*/
|
||||
public $sockets;
|
||||
|
||||
public function __construct($server, $conn)
|
||||
{
|
||||
$this->server = $server;
|
||||
$this->conn = $conn;
|
||||
$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 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
|
||||
*/
|
||||
|
||||
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['/'])) {
|
||||
$this->connectBuffer[$name] = $name;
|
||||
return;
|
||||
}
|
||||
$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) {
|
||||
$this->connect($name);
|
||||
}
|
||||
$this->connectBuffer = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnects from all namespaces and closes transport.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
public function disconnect()
|
||||
{
|
||||
foreach ($this->sockets as $socket) {
|
||||
$socket->disconnect();
|
||||
}
|
||||
$this->sockets = [];
|
||||
$this->close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a socket. Called by each `Socket`.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
public function remove($socket)
|
||||
{
|
||||
if (isset($this->sockets[$socket->id])) {
|
||||
$nsp = $this->sockets[$socket->id]->nsp->name;
|
||||
unset($this->sockets[$socket->id]);
|
||||
unset($this->nsps[$nsp]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the underlying connection.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
public function close()
|
||||
{
|
||||
if (empty($this->conn)) {
|
||||
return;
|
||||
}
|
||||
if ('open' === $this->conn->readyState) {
|
||||
$this->conn->close();
|
||||
$this->onclose('forced server close');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
// not broadcasting, need to encode
|
||||
$encodedPackets = $this->encoder->encode($packet);
|
||||
$this->writeToEngine($encodedPackets, $volatile);
|
||||
} else { // a broadcast pre-encodes a packet
|
||||
$this->writeToEngine($packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function writeToEngine($encodedPackets, $volatile = false)
|
||||
{
|
||||
if ($volatile) {
|
||||
echo new Exception('volatile');
|
||||
}
|
||||
if ($volatile && ! $this->conn->transport->writable) {
|
||||
return;
|
||||
}
|
||||
if (isset($encodedPackets['nsp'])) {
|
||||
unset($encodedPackets['nsp']);
|
||||
}
|
||||
foreach ($encodedPackets as $packet) {
|
||||
$this->conn->write($packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called with incoming transport data.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
public function ondata($data)
|
||||
{
|
||||
try {
|
||||
// todo chek '2["chat message","2"]' . "\0" . ''
|
||||
$this->decoder->add(trim($data));
|
||||
} catch (Exception $e) {
|
||||
$this->onerror($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when parser fully decodes a packet.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
public function ondecoded($packet)
|
||||
{
|
||||
if (Parser::CONNECT == $packet['type']) {
|
||||
$this->connect($packet['nsp']);
|
||||
} else {
|
||||
if (isset($this->nsps[$packet['nsp']])) {
|
||||
$this->nsps[$packet['nsp']]->onpacket($packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an error.
|
||||
*
|
||||
* @param {Objcet} error object
|
||||
* @api private
|
||||
*/
|
||||
public function onerror($err)
|
||||
{
|
||||
foreach ($this->sockets as $socket) {
|
||||
$socket->onerror($err);
|
||||
}
|
||||
$this->onclose('client error');
|
||||
}
|
||||
|
||||
/**
|
||||
* Called upon transport close.
|
||||
*
|
||||
* @param {String} reason
|
||||
* @api private
|
||||
*/
|
||||
public function onclose($reason)
|
||||
{
|
||||
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) {
|
||||
$socket->onclose($reason);
|
||||
}
|
||||
$this->sockets = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up event listeners.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
if (! $this->conn) {
|
||||
return;
|
||||
}
|
||||
$this->conn->removeAllListeners();
|
||||
$this->decoder->removeAllListeners();
|
||||
$this->encoder->removeAllListeners();
|
||||
$this->server = $this->conn = $this->encoder = $this->decoder = $this->request = $this->nsps = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user