continue drafting socket

This commit is contained in:
Dennis Eichhorn 2019-11-03 23:25:34 +01:00
parent 8d4bdc992e
commit e26963c3a8
23 changed files with 681 additions and 470 deletions

View File

@ -4,7 +4,7 @@
*
* PHP Version 7.4
*
* @package phpOMS\Socket\Packets
* @package phpOMS\Message\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -12,19 +12,21 @@
*/
declare(strict_types=1);
namespace phpOMS\Socket\Packets;
namespace phpOMS\Message\Socket;
use phpOMS\Message\HeaderAbstract;
/**
* Server class.
*
* Parsing/serializing arrays to and from php file
*
* @package phpOMS\Socket\Packets
* @package phpOMS\Message\Socket
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class Header implements \Serializable
class Header extends HeaderAbstract implements \Serializable
{
private $sendFrom = null;
@ -54,6 +56,14 @@ class Header implements \Serializable
*/
private $subtype = 0;
/**
* Header.
*
* @var string[][]
* @since 1.0.0
*/
private array $header = [];
public function getSendFrom()
{
return $this->sendFrom;
@ -176,4 +186,43 @@ class Header implements \Serializable
public function unserialize($string) : void
{
}
/**
* {@inheritdoc}
*/
public function getProtocolVersion() : string
{
return 'Socket/1.1';
}
/**
* {@inheritdoc}
*/
public function set(string $key, string $header, bool $overwrite = false) : bool
{
return true;
}
/**
* {@inheritdoc}
*/
public function get(string $key = null) : array
{
return $key === null ? $this->header : ($this->header[\strtolower($key)] ?? []);
}
/**
* {@inheritdoc}
*/
public function has(string $key) : bool
{
return isset($this->header[$key]);
}
/**
* {@inheritdoc}
*/
public function generate(int $code) : void
{
}
}

View File

@ -0,0 +1,88 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package phpOMS\Message\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Message\Socket;
use phpOMS\Socket\Server\ClientManager;
use phpOMS\Dispatcher\Dispatcher;
use phpOMS\Router\SocketRouter;
use phpOMS\Message\Socket\Request;
use phpOMS\Message\Socket\Response;
/**
* Server class.
*
* Parsing/serializing arrays to and from php file
*
* @package phpOMS\Message\Socket
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class PacketManager
{
/**
* Socket router.
*
* @var SocketRouter
* @since 1.0.0
*/
private SocketRouter $router;
/**
* Dispatcher.
*
* @var Dispatcher
* @since 1.0.0
*/
private Dispatcher $dispatcher;
/**
* Constructor.
*
* @param SocketRouter $router Socket router
* @param Dispatcher $dispatcher Dispatcher
*
* @since 1.0.0
*/
public function __construct(SocketRouter $router, Dispatcher $dispatcher)
{
$this->router = $router;
$this->dispatcher = $dispatcher;
}
/**
* Handle package.
*
* @param string $data Package data
*
* @return void
*
* @since 1.0.0
*/
public function handle(string $data, $client) : void
{
$request = new Request($data);
$request->getHeader()->setAccount($client->getAccount()->getId());
$response = new Response();
$this->dispatcher->dispatch(
$this->router->route($data, 'Socket', 1, $client->getAccount()),
$request,
$response
);
}
}

View File

@ -4,7 +4,7 @@
*
* PHP Version 7.4
*
* @package phpOMS\Socket\Packets
* @package phpOMS\Message\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
@ -12,14 +12,14 @@
*/
declare(strict_types=1);
namespace phpOMS\Socket\Packets;
namespace phpOMS\Message\Socket;
use phpOMS\Stdlib\Base\Enum;
/**
* Packet type enum.
*
* @package phpOMS\Socket\Packets
* @package phpOMS\Message\Socket
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
@ -36,5 +36,5 @@ abstract class PacketType extends Enum
public const LOGIN = 7; /* Login (server/sender) */
public const LOGOUT = 8; /* Logout (server/sender) */
public const CMD = 9; /* Other command */
public const MODULE = 999999999; /* Module packet ??? */
public const DOWNLOAD = 10; /* Download */
}

View File

@ -4,16 +4,62 @@
*
* PHP Version 7.4
*
* @package TBD
* @package phpOMS\Message\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Message\Socket;
class Request
{
use phpOMS\Message\RequestAbstract;
final class Request extends RequestAbstract
{
public function __construct()
{
$this->header = new Header();
}
/**
* {@inheritdoc}
*/
public function getOrigin() : string
{
return '127.0.0.1';
}
/**
* Get request language
*
* @return string
*
* @since 1.0.0
*/
public function getRequestLanguage() : string
{
return 'en';
}
/**
* Get request locale
*
* @return string
*
* @since 1.0.0
*/
public function getLocale() : string
{
return 'en_US';
}
/**
* {@inheritdoc}
*/
public function getBody() : string
{
return '';
}
}

View File

@ -4,16 +4,177 @@
*
* PHP Version 7.4
*
* @package TBD
* @package phpOMS\Message\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Message\Socket;
class Response
{
use phpOMS\Message\ResponseAbstract;
use phpOMS\Contract\RenderableInterface;
final class Response extends ResponseAbstract implements RenderableInterface
{
/**
* Set response.
*
* @param array $response Response to set
*
* @return void
*
* @since 1.0.0
*/
public function setResponse(array $response) : void
{
$this->response = $response;
}
/**
* Remove response by ID.
*
* @param mixed $id Response ID
*
* @return bool
*
* @since 1.0.0
*/
public function remove($id) : bool
{
if (isset($this->response[$id])) {
unset($this->response[$id]);
return true;
}
return false;
}
/**
* {@inheritdoc}
*/
public function getJsonData() : array
{
return \json_decode($this->getRaw(), true);
}
/**
* {@inheritdoc}
*/
public function getBody(bool $optimize = false) : string
{
return $this->render($optimize);
}
/**
* Generate response based on header.
*
* @param bool $optimize Optimize response / minify
*
* @return string
*
* @since 1.0.0
*/
public function render(bool $optimize = false) : string
{
$types = $this->header->get('Content-Type');
foreach ($types as $type) {
if (\stripos($type, MimeType::M_JSON) !== false) {
return (string) \json_encode($this->jsonSerialize());
}
}
return $this->getRaw($optimize);
}
/**
* Generate raw response.
*
* @param bool $optimize Optimize response / minify
*
* @return string
*
* @throws \Exception
*
* @since 1.0.0
*/
private function getRaw(bool $optimize = false) : string
{
$render = '';
foreach ($this->response as $key => $response) {
$render .= StringUtils::stringify($response);
}
if ($optimize) {
return $this->removeWhitespaceAndLineBreak($render);
}
return $render;
}
/**
* Remove whitespace and line break from render
*
* @param string $render Rendered string
*
* @return string
*
* @since 1.0.0
*/
private function removeWhitespaceAndLineBreak(string $render) : string
{
$types = $this->header->get('Content-Type');
if (\stripos($types[0], MimeType::M_HTML) !== false) {
$clean = \preg_replace('/(?s)<pre[^<]*>.*?<\/pre>(*SKIP)(*F)|(\s{2,}|\n|\t)/', ' ', $render);
return \trim($clean ?? '');
}
return $render;
}
/**
* {@inheritdoc}
* @todo: this whole workflow with json got improved a little bit but this part looks bad. do i really need so much code or could i simplify it
*/
public function toArray() : array
{
$result = [];
try {
foreach ($this->response as $key => $response) {
if ($response instanceof View) {
$result[] = $response->toArray();
} elseif (\is_array($response)) {
$result[] = $response;
} elseif (\is_scalar($response)) {
$result[] = $response;
} elseif ($response instanceof \JsonSerializable) {
$result[] = $response->jsonSerialize();
} elseif ($response === null) {
continue;
} else {
throw new \Exception('Wrong response type');
}
}
} catch (\Exception $e) {
FileLogger::getInstance('', false)
->error(
FileLogger::MSG_FULL, [
'message' => $e->getMessage(),
'line' => __LINE__,
'file' => self::class,
]
);
$result = [];
} finally {
return $result;
}
}
}

View File

@ -14,8 +14,10 @@ declare(strict_types=1);
namespace phpOMS\Socket\Client;
use phpOMS\Socket\CommandManager;
use phpOMS\Socket\SocketAbstract;
use phpOMS\ApplicationAbstract;
use phpOMS\Socket\Server\ClientManager;
use phpOMS\Message\Socket\PacketManager;
/**
* Client socket class.
@ -27,21 +29,36 @@ use phpOMS\Socket\SocketAbstract;
*/
class Client extends SocketAbstract
{
private $commands;
/**
* Packet manager.
*
* @var PacketManager
* @since 1.0.0
*/
private $packetManager = null;
/**
* Socket application.
*
* @var SocketApplication
* @since 1.0.0
*/
private $app = null;
private $clientManager = null;
private array $packets = [];
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct()
public function __construct(ApplicationAbstract $app)
{
$this->commands = new CommandManager();
/** @noinspection PhpUnusedParameterInspection */
$this->commands->attach('disconnect', function ($conn, $para) : void {
$this->disconnect();
}, $this);
$this->app = $app;
$this->clientManager = new ClientManager();
$this->packetManager = new PacketManager($this->app->router, $this->app->dispatcher);
}
/**
@ -70,15 +87,16 @@ class Client extends SocketAbstract
public function run() : void
{
\socket_connect($this->sock, $this->ip, $this->port);
$i = 0;
$errorCounter = 0;
while ($this->run) {
try {
++$i;
$msg = 'disconnect';
\socket_write($this->sock, $msg, \strlen($msg));
if (!empty($this->packets)) {
$msg = \array_shift($this->packets);
\socket_write($this->sock, $msg, \strlen($msg));
}
$read = [$this->sock];
@ -97,6 +115,8 @@ class Client extends SocketAbstract
if (\count($read) > 0) {
$data = \socket_read($this->sock, 1024);
var_dump($data);
/* Server no data */
if ($data === false) {
continue;
@ -122,6 +142,16 @@ class Client extends SocketAbstract
$this->close();
}
public function shutdown() : void
{
$this->run = false;
}
public function addPacket($packet) : void
{
$this->packets[] = $packet;
}
/**
* {@inheritdoc}
*/

View File

@ -14,6 +14,8 @@ declare(strict_types=1);
namespace phpOMS\Socket\Client;
use phpOMS\Account\Account;
/**
* Client socket class.
*
@ -29,10 +31,12 @@ class ClientConnection
private $handshake = false;
private $pid = null;
private $connected = true;
private Account $account;
public function __construct($id, $socket)
public function __construct(Account $account, $socket)
{
$this->id = $id;
$this->id = $account->getId();
$this->account = $account;
$this->socket = $socket;
}
@ -41,6 +45,11 @@ class ClientConnection
return $this->id;
}
public function getAccount() : Account
{
return $this->account;
}
public function getSocket()
{
return $this->socket;

View File

@ -1,119 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package phpOMS\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Socket;
/**
* CommandManager class.
*
* @package phpOMS\Socket
* @since 1.0.0
*
* @todo : Hey, this looks like a copy of an event manager!
*/
class CommandManager implements \Countable
{
/**
* Commands.
*
* @var mixed[]
* @since 1.0.0
*/
private $commands = [];
/**
* Commands.
*
* @var int
* @since 1.0.0
*/
private $count = 0;
/**
* Constructor.
*
* @since 1.0.0
*/
public function __construct()
{
}
/**
* Attach new command.
*
* @param string $cmd Command ID
* @param mixed $callback Function callback
* @param mixed $source Provider
*
* @return void
*
* @since 1.0.0
*/
public function attach(string $cmd, $callback, $source) : void
{
$this->commands[$cmd] = [$callback, $source];
++$this->count;
}
/**
* Detach existing command.
*
* @param string $cmd Command ID
* @param mixed $source Provider
*
* @return void
*
* @since 1.0.0
*/
public function detach(string $cmd, $source) : void
{
if (\array_key_exists($cmd, $this->commands)) {
unset($this->commands[$cmd]);
--$this->count;
}
}
/**
* Trigger command.
*
* @param string $cmd Command ID
* @param mixed $conn Client ID
* @param mixed $para Parameters to pass
*
* @return bool|mixed
*
* @since 1.0.0
*/
public function trigger(string $cmd, $conn, $para)
{
if (\array_key_exists($cmd, $this->commands)) {
return $this->commands[$cmd][0]($conn, $para);
}
return false;
}
/**
* Count commands.
*
* @return int
*
* @since 1.0.0
*/
public function count() : int
{
return $this->count;
}
}

View File

@ -1,98 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package phpOMS\Socket\Packets
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Socket\Packets;
/**
* Server class.
*
* Parsing/serializing arrays to and from php file
*
* @package phpOMS\Socket\Packets
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
abstract class PacketAbstract implements \Serializable
{
/**
* Packet header.
*
* @var Header
* @since 1.0.0
*/
private $header = null;
/**
* Stringify packet.
*
* This is using a json format
*
* @return string
*
* @since 1.0.0
*/
abstract public function __toString();
/**
* Stringify packet.
*
* This is using a json format
*
* @return string Json string
*
* @since 1.0.0
*/
abstract public function serialize();
/**
* Unserialize packet.
*
* This is using a json format
*
* @param string $string Json string
*
* @return void
*
* @since 1.0.0
*/
abstract public function unserialize($string) : void;
/**
* Get packet header.
*
* @return Header
*
* @since 1.0.0
*/
public function getHeader() : Header
{
return $this->header;
}
/**
* Set packet header.
*
* @param Header $header Header
*
* @return void
*
* @since 1.0.0
*/
public function setHeader(Header $header) : void
{
$this->header = $header;
}
}

View File

@ -1,76 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package phpOMS\Socket\Packets
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Socket\Packets;
use phpOMS\Socket\CommandManager;
use phpOMS\Socket\Server\ClientManager;
/**
* Server class.
*
* Parsing/serializing arrays to and from php file
*
* @package phpOMS\Socket\Packets
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class PacketManager
{
/**
* Command Manager.
*
* @var CommandManager
* @since 1.0.0
*/
private $commandManager = null;
/**
* Client Manager.
*
* @var ClientManager
* @since 1.0.0
*/
private $clientManager = null;
/**
* Constructor.
*
* @param CommandManager $cmd Command Manager
* @param ClientManager $user Client Manager
*
* @since 1.0.0
*/
public function __construct(CommandManager $cmd, ClientManager $user)
{
$this->commandManager = $cmd;
$this->clientManager = $user;
}
/**
* Handle package.
*
* @param string $data Package data
*
* @return void
*
* @since 1.0.0
*/
public function handle(string $data, $client) : void
{
echo $data;
}
}

View File

@ -28,7 +28,7 @@ class ClientManager
public function get($id)
{
return $this->clients[$id] ?? new NullClientConnection(\uniqid(), null);
return $this->clients[$id] ?? new NullClientConnection($id, null);
}
public function getBySocket($socket)
@ -39,7 +39,7 @@ class ClientManager
}
}
return new NullClientConnection(\uniqid(), null);
return new NullClientConnection($id, null);
}
public function remove($id)

View File

@ -14,10 +14,12 @@ declare(strict_types=1);
namespace phpOMS\Socket\Server;
use phpOMS\Account\Account;
use phpOMS\Socket\Client\ClientConnection;
use phpOMS\Socket\CommandManager;
use phpOMS\Socket\Packets\PacketManager;
use phpOMS\Socket\SocketAbstract;
use phpOMS\Message\Socket\PacketManager;
use Socket\SocketApplication;
use phpOMS\ApplicationAbstract;
/**
* Server class.
@ -61,7 +63,7 @@ class Server extends SocketAbstract
/**
* Socket application.
*
* @var \Socket\SocketApplication
* @var SocketApplication
* @since 1.0.0
*/
private $app = null;
@ -69,15 +71,15 @@ class Server extends SocketAbstract
/**
* Constructor.
*
* @param \Socket\SocketApplication $app socketApplication
* @param SocketApplication $app socketApplication
*
* @since 1.0.0
*/
public function __construct($app)
public function __construct(ApplicationAbstract $app)
{
$this->app = $app;
$this->clientManager = new ClientManager();
$this->packetManager = new PacketManager(new CommandManager(), new ClientManager());
$this->packetManager = new PacketManager($this->app->router, $this->app->dispatcher);
}
/**
@ -180,7 +182,7 @@ class Server extends SocketAbstract
@\socket_set_nonblock($this->sock);
$this->conn[] = $this->sock;
$this->app->logger->info('Start running...');
$this->app->logger->info('Is running...');
while ($this->run) {
$read = $this->conn;
@ -201,31 +203,46 @@ class Server extends SocketAbstract
} else {
$client = $this->clientManager->getBySocket($socket);
$data = @\socket_read($socket, 1024, \PHP_NORMAL_READ);
var_dump($data);
if ($data === false) {
\socket_close($socket);
}
$data = \is_string($data) ? \trim($data) : '';
if (!$client->getHandshake()) {
$this->app->logger->debug('Doing handshake...');
if ($this->handshake($client, $data)) {
$client->setHandshake(true);
$this->app->logger->debug('Handshake succeeded.');
} else {
$this->app->logger->debug('Handshake failed.');
$this->disconnectClient($client);
}
} else {
// todo: maybe implement shutdown and help for testing?
$this->packetManager->handle($this->unmask($data), $client);
$this->packetManager->handle($data, $client);
}
}
}
}
$this->app->logger->info('Is shutdown...');
$this->close();
}
public function shutdown($request) : void
{
$msg = 'shutdown' . "\n";
\socket_write($this->clientManager->get($request->getHeader()->getAccount())->getSocket(), $msg, \strlen($msg));
$this->run = false;
}
public function connectClient($socket) : void
{
$this->app->logger->debug('Connecting client...');
$this->clientManager->add($client = new ClientConnection(\uniqid(), $socket));
$this->app->accountManager->add(new Account(1));
$this->clientManager->add($client = new ClientConnection(new Account(1), $socket));
$this->conn[$client->getId()] = $socket;
$this->app->logger->debug('Connected client.');
}

View File

@ -1,32 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package phpOMS\Socket
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Socket;
use phpOMS\Stdlib\Base\Enum;
/**
* Socket type enum.
*
* @package phpOMS\Socket
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
abstract class SocketType extends Enum
{
public const TCP_SERVER = 'server';
public const TCP_CLIENT = 'client';
public const WEB_SOCKET = 'ws';
}

View File

@ -12,7 +12,7 @@
*/
declare(strict_types=1);
namespace phpOMS\tests\Socket\Packets;
namespace phpOMS\tests\Message\Socket;
/**
* @internal

View File

@ -12,7 +12,7 @@
*/
declare(strict_types=1);
namespace phpOMS\tests\Socket\Packets;
namespace phpOMS\tests\Message\Socket;
/**
* @internal

View File

@ -0,0 +1,40 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Message\Socket;
use phpOMS\Message\Socket\PacketType;
/**
* @internal
*/
class PacketTypeTest extends \PHPUnit\Framework\TestCase
{
public function testEnums() : void
{
self::assertCount(11, PacketType::getConstants());
self::assertEquals(PacketType::getConstants(), \array_unique(PacketType::getConstants()));
self::assertEquals(0, PacketType::CONNECT);
self::assertEquals(1, PacketType::DISCONNECT);
self::assertEquals(2, PacketType::KICK);
self::assertEquals(3, PacketType::PING);
self::assertEquals(4, PacketType::HELP);
self::assertEquals(5, PacketType::RESTART);
self::assertEquals(6, PacketType::MSG);
self::assertEquals(7, PacketType::LOGIN);
self::assertEquals(8, PacketType::LOGOUT);
self::assertEquals(9, PacketType::CMD);
self::assertEquals(10, PacketType::DOWNLOAD);
}
}

View File

@ -14,13 +14,94 @@ declare(strict_types=1);
namespace phpOMS\tests\Socket\Client;
use Model\CoreSettings;
use phpOMS\Account\AccountManager;
use phpOMS\ApplicationAbstract;
use phpOMS\DataStorage\Cache\CachePool;
use phpOMS\Dispatcher\Dispatcher;
use phpOMS\Event\EventManager;
use phpOMS\Localization\L11nManager;
use phpOMS\Log\FileLogger;
use phpOMS\Module\ModuleManager;
use phpOMS\Router\SocketRouter;
use phpOMS\Socket\Client\Client;
/**
* @internal
*/
class ClientTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder() : void
protected $app;
public static function setUpBeforeClass() : void
{
if (\file_exists(__DIR__ . '/client.log')) {
\unlink(__DIR__ . '/client.log');
}
if (\file_exists(__DIR__ . '/server.log')) {
\unlink(__DIR__ . '/server.log');
}
}
protected function setUp() : void
{
$this->app = new class() extends ApplicationAbstract
{
protected string $appName = 'Socket';
};
$this->app->logger = new FileLogger(__DIR__ . '/client.log', false);
$this->app->dbPool = $GLOBALS['dbpool'];
$this->app->orgId = 1;
$this->app->cachePool = new CachePool($this->app->dbPool);
$this->app->accountManager = new AccountManager($GLOBALS['session']);
$this->app->appSettings = new CoreSettings($this->app->dbPool->get());
$this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules');
$this->app->dispatcher = new Dispatcher($this->app);
$this->app->eventManager = new EventManager($this->app->dispatcher);
$this->app->eventManager->importFromFile(__DIR__ . '/../../../Socket/Hooks.php');
$this->app->l11nManager = new L11nManager($this->app->appName);
$this->app->router = new SocketRouter();
}
protected function tearDown() : void
{
\unlink(__DIR__ . '/client.log');
\unlink(__DIR__ . '/server.log');
}
public function testSetupTCPSocket() : void
{
self::markTestIncomplete();
return;
$pipes = [];
$process = \proc_open('php ClientTestHelper.php', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, __DIR__);
\sleep(5);
$socket = new Client($this->app);
$socket->create('127.0.0.1', $GLOBALS['CONFIG']['socket']['master']['port']);
$socket->addPacket('handshake' . "\r");
$socket->addPacket('help' . "\r");
$socket->addPacket('shutdown' . "\r");
$this->app->router->add('^shutdown$', function() use ($socket) { $socket->shutdown(); });
$socket->run();
self::assertEquals(
'Creating socket...' . "\n"
. 'Binding socket...' . "\n"
. 'Start listening...' . "\n"
. 'Is running...' . "\n"
. 'Connecting client...' . "\n"
. 'Connected client.' . "\n"
. 'Doing handshake...' . "\n"
. 'Handshake succeeded.' . "\n"
. 'Is shutdown...' . "\n",
\file_get_contents(__DIR__ . '/server.log')
);
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package test
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link http://orange-management.com
*/
declare(strict_types=1);
namespace phpOMS\tests\Socket\Client;
use phpOMS\Socket\Server\Server;
use Model\CoreSettings;
use phpOMS\Account\AccountManager;
use phpOMS\ApplicationAbstract;
use phpOMS\DataStorage\Cache\CachePool;
use phpOMS\Dispatcher\Dispatcher;
use phpOMS\Event\EventManager;
use phpOMS\Localization\L11nManager;
use phpOMS\Log\FileLogger;
use phpOMS\Module\ModuleManager;
use phpOMS\Router\SocketRouter;
use phpOMS\DataStorage\Database\DatabasePool;
use phpOMS\DataStorage\Database\DataMapperAbstract;
use phpOMS\DataStorage\Session\HttpSession;
require_once __DIR__ . '/../../../Autoloader.php';
$config = require_once __DIR__ . '/../../../../config.php';
$GLOBALS['dbpool'] = new DatabasePool();
$GLOBALS['dbpool']->create('admin', $config['db']['core']['masters']['admin']);
$GLOBALS['dbpool']->create('select', $config['db']['core']['masters']['select']);
$GLOBALS['dbpool']->create('update', $config['db']['core']['masters']['update']);
$GLOBALS['dbpool']->create('insert', $config['db']['core']['masters']['insert']);
$GLOBALS['dbpool']->create('schema', $config['db']['core']['masters']['schema']);
$httpSession = new HttpSession();
$GLOBALS['session'] = $httpSession;
DataMapperAbstract::setConnection($GLOBALS['dbpool']->get());
$app = new class() extends ApplicationAbstract
{
protected string $appName = 'Socket';
};
$app->logger = FileLogger::getInstance(__DIR__ . '/server.log', true);
$app->dbPool = $GLOBALS['dbpool'];
$app->orgId = 1;
$app->cachePool = new CachePool($app->dbPool);
$app->accountManager = new AccountManager($GLOBALS['session']);
$app->appSettings = new CoreSettings($app->dbPool->get());
$app->moduleManager = new ModuleManager($app, __DIR__ . '/../../../../Modules');
$app->dispatcher = new Dispatcher($app);
$app->eventManager = new EventManager($app->dispatcher);
$app->eventManager->importFromFile(__DIR__ . '/../../../Socket/Hooks.php');
$app->l11nManager = new L11nManager($app->appName);
$app->router = new SocketRouter();
$socket = new Server($app);
$socket->create('127.0.0.1', $config['socket']['master']['port']);
$socket->setLimit(1);
$app->router->add('^shutdown$', function($app, $request) use ($socket) { $socket->shutdown($request); });
$socket->run();

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Socket;
require_once __DIR__ . '/../Autoloader.php';
/**
* @internal
*/
class CommandManagerTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder() : void
{
self::markTestIncomplete();
}
}

View File

@ -1,26 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Socket\Packets;
/**
* @internal
*/
class PacketTypeTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder() : void
{
self::markTestIncomplete();
}
}

View File

@ -15,10 +15,7 @@ declare(strict_types=1);
namespace phpOMS\tests\Socket\Server;
use Model\CoreSettings;
use Modules\Admin\Models\AccountPermission;
use phpOMS\Account\Account;
use phpOMS\Account\AccountManager;
use phpOMS\Account\PermissionType;
use phpOMS\ApplicationAbstract;
use phpOMS\DataStorage\Cache\CachePool;
use phpOMS\Dispatcher\Dispatcher;
@ -26,15 +23,26 @@ use phpOMS\Event\EventManager;
use phpOMS\Localization\L11nManager;
use phpOMS\Log\FileLogger;
use phpOMS\Module\ModuleManager;
use phpOMS\Router\WebRouter;
use phpOMS\Socket\Server\Server;
use phpOMS\Router\SocketRouter;
/**
* @internal
*/
class ServerTest extends \PHPUnit\Framework\TestCase
{
protected $app = null;
protected $app;
public static function setUpBeforeClass() : void
{
if (\file_exists(__DIR__ . '/client.log')) {
\unlink(__DIR__ . '/client.log');
}
if (\file_exists(__DIR__ . '/server.log')) {
\unlink(__DIR__ . '/server.log');
}
}
protected function setUp() : void
{
@ -43,7 +51,7 @@ class ServerTest extends \PHPUnit\Framework\TestCase
protected string $appName = 'Socket';
};
$this->app->logger = FileLogger::getInstance(__DIR__ . '/server.log', true);
$this->app->logger = new FileLogger(__DIR__ . '/server.log', false);
$this->app->dbPool = $GLOBALS['dbpool'];
$this->app->orgId = 1;
$this->app->cachePool = new CachePool($this->app->dbPool);
@ -54,29 +62,46 @@ class ServerTest extends \PHPUnit\Framework\TestCase
$this->app->eventManager = new EventManager($this->app->dispatcher);
$this->app->eventManager->importFromFile(__DIR__ . '/../../../Socket/Hooks.php');
$this->app->l11nManager = new L11nManager($this->app->appName);
$this->app->router = new WebRouter();
$this->app->router = new SocketRouter();
}
protected function tearDown() : void
{
/*
\delete(__DIR__ . '/client.log');
\delete(__DIR__ . '/server.log');*/
\unlink(__DIR__ . '/client.log');
\unlink(__DIR__ . '/server.log');
}
public function testSetupTCPSocket() : void
{
self::markTestIncomplete();
return;
$pipes = [];
$process = \proc_open('php ServerTestHelper.php 127.0.0.1', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, __DIR__);
$process = \proc_open('php ServerTestHelper.php', [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes, __DIR__);
$socket = new Server($this->app);
$socket->create('127.0.0.1', $GLOBALS['CONFIG']['socket']['master']['port']);
$socket->setLimit(1);
$this->app->router->add('^shutdown$', function($app, $request) use ($socket) { $socket->shutdown($request); });
$socket->run();
// todo: assert content of server.log
// todo: assert content of client.log
self::assertTrue(\file_exists(__DIR__ . '/server.log'));
self::assertEquals(
'Creating socket...' . "\n"
. 'Binding socket...' . "\n"
. 'Start listening...' . "\n"
. 'Is running...' . "\n"
. 'Connecting client...' . "\n"
. 'Connected client.' . "\n"
. 'Doing handshake...' . "\n"
. 'Handshake succeeded.' . "\n"
. 'Is shutdown...' . "\n",
\file_get_contents(__DIR__ . '/server.log')
);
self::assertTrue(\file_exists(__DIR__ . '/client.log'));
$client = \file_get_contents(__DIR__ . '/client.log');
self::assertStringContainsString('Sending: handshake', $client);
self::assertStringContainsString('Sending: help', $client);
self::assertStringContainsString('Sending: shutdown', $client);
}
}

View File

@ -36,12 +36,13 @@ try {
handleSocketError($sock);
$msgs = [
'handshake' . "\r", // this needs to happen first (of course the submitted handshake data needs to be implemented correctl. just sending this is of course bad!)
'help' . "\r",
'shutdown' . "\r",
];
foreach ($msgs as $msg) {
var_dump($msg);
\file_put_contents(__DIR__ . '/client.log', 'Sending: ' . $msg . "\n", \FILE_APPEND);
@\socket_write($sock, $msg, \strlen($msg));
handleSocketError($sock);
@ -56,7 +57,7 @@ try {
/* Normalize */
$data = \trim($data);
\file_put_contents(__DIR__ . '/client.log', $data, \FILE_APPEND);
\file_put_contents(__DIR__ . '/client.log', 'Receiving' . $data . "\n", \FILE_APPEND);
}
handleSocketError($sock);

View File

@ -1,28 +0,0 @@
<?php
/**
* Orange Management
*
* PHP Version 7.4
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\tests\Socket;
require_once __DIR__ . '/../Autoloader.php';
/**
* @internal
*/
class SocketTypeTest extends \PHPUnit\Framework\TestCase
{
public function testPlaceholder() : void
{
self::markTestIncomplete();
}
}