From 9e3c226790bb882cca9c88d76fdf4a2d52de2639 Mon Sep 17 00:00:00 2001 From: Aliaksandr Harshkou Date: Sat, 17 Feb 2024 01:39:27 +0300 Subject: [PATCH 1/7] hw5 --- README.md | 6 +++- composer.json | 13 ++++++++ composer.lock | 18 +++++++++++ config/config.ini | 3 ++ data/.gitignore | 2 ++ docker-compose.yml | 21 +++++++++++++ docker/php/Dockerfile | 19 ++++++++++++ public/index.php | 15 +++++++++ src/App.php | 31 +++++++++++++++++++ src/Chat.php | 72 +++++++++++++++++++++++++++++++++++++++++++ src/Client.php | 29 +++++++++++++++++ src/Config.php | 30 ++++++++++++++++++ src/Server.php | 38 +++++++++++++++++++++++ 13 files changed, 296 insertions(+), 1 deletion(-) create mode 100755 composer.json create mode 100644 composer.lock create mode 100644 config/config.ini create mode 100644 data/.gitignore create mode 100644 docker-compose.yml create mode 100644 docker/php/Dockerfile create mode 100644 public/index.php create mode 100644 src/App.php create mode 100644 src/Chat.php create mode 100644 src/Client.php create mode 100644 src/Config.php create mode 100644 src/Server.php diff --git a/README.md b/README.md index b44ec14b8..ce7a75b4f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # PHP_2024 -https://otus.ru/lessons/razrabotchik-php/?utm_source=github&utm_medium=free&utm_campaign=otus +### Запускк + +1. docker-compose up -d +2. docker-compose run app-server php index.php server +3. docker-compose run app-client php index.php client diff --git a/composer.json b/composer.json new file mode 100755 index 000000000..9d51767bf --- /dev/null +++ b/composer.json @@ -0,0 +1,13 @@ +{ + "name": "ahor/hw5", + "type": "project", + "autoload": { + "psr-4": { + "Ahor\\Hw5\\": "src/" + } + }, + "require": { + "ext-sockets": "*", + "ext-readline": "*" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 000000000..3bfa3877e --- /dev/null +++ b/composer.lock @@ -0,0 +1,18 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "24815006af63058878478bda805248df", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/config/config.ini b/config/config.ini new file mode 100644 index 000000000..f42ae69a3 --- /dev/null +++ b/config/config.ini @@ -0,0 +1,3 @@ +[socket] +file_name = /app/data/tmp.sock +max_len = 256 diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..f1154a8d4 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: "3" + +services: + app-server: + build: docker/php + volumes: + - .:/app + networks: + - net + working_dir: /app/public + app-client: + build: docker/php + volumes: + - .:/app + working_dir: /app/public + networks: + - net + +networks: + net: + driver: bridge diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 000000000..e2ea9fb77 --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,19 @@ +FROM php:8.3.2-fpm + +RUN apt-get update && apt-get install -y \ + zlib1g-dev \ + libmemcached-dev \ + libssl-dev \ + git + +RUN docker-php-ext-install pdo pdo_mysql sockets && docker-php-ext-enable pdo pdo_mysql sockets + +RUN pecl install redis-6.0.0 memcached-3.2.0 && docker-php-ext-enable redis memcached + +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/bin --filename=composer --quiet --version=2.6.6 + +WORKDIR /app + +EXPOSE 9000 + +CMD ["php-fpm"] diff --git a/public/index.php b/public/index.php new file mode 100644 index 000000000..5a27d8d28 --- /dev/null +++ b/public/index.php @@ -0,0 +1,15 @@ +run($argv[1] ?? null); +} catch (Exception $e) { + echo "ERROR" . PHP_EOL; + echo $e->getMessage() . PHP_EOL; +} diff --git a/src/App.php b/src/App.php new file mode 100644 index 000000000..c515c2cea --- /dev/null +++ b/src/App.php @@ -0,0 +1,31 @@ +config = new Config($fileConfigName); + } + + public function run($arg): void + { + switch ($arg) { + case 'server': + $server = new Server($this->config); + $server->start(); + + break; + case 'client': + $client = new Client($this->config); + $client->start(); + + break; + default: + throw new \DomainException('Ошибка аргумента, server или client' . PHP_EOL); + } + } +} diff --git a/src/Chat.php b/src/Chat.php new file mode 100644 index 000000000..980e03d06 --- /dev/null +++ b/src/Chat.php @@ -0,0 +1,72 @@ +config->socketFile)) { + unlink($this->config->socketFile); + } + + $result = socket_create(AF_UNIX, SOCK_STREAM, 0); + if ($result === false) { + throw new \DomainException("Ошибка создания сокета"); + } + + $this->socket = $result; + } + + public function listen(): void + { + socket_listen($this->socket); + } + + public function bind(): void + { + socket_bind($this->socket, $this->config->socketFile); + } + + public function close(): void + { + socket_close($this->socket); + } + + public function accept() + { + return socket_accept($this->socket); + } + + public function receive($socket): string + { + socket_recv($socket, $message, $this->config->maxLen, 0); + + return $message ?? ''; + } + + + public function connect(): void + { + socket_connect($this->socket, $this->config->socketFile); + } + + public function send(string $message): void + { + socket_write($this->socket, $message, strlen($message)); + } + + abstract public function start(); +} + diff --git a/src/Client.php b/src/Client.php new file mode 100644 index 000000000..8483fcbda --- /dev/null +++ b/src/Client.php @@ -0,0 +1,29 @@ +create(); + $this->connect(); + + $run = true; + while ($run) { + echo 'Введите сообщение и нажмите Enter: ' . PHP_EOL; + + $message = readline(); + $this->send($message); + + if ($message === 'stop') { + $run = false; + } + } + + $this->close(); + } +} diff --git a/src/Config.php b/src/Config.php new file mode 100644 index 000000000..8394f2975 --- /dev/null +++ b/src/Config.php @@ -0,0 +1,30 @@ +socketFile = $config['socket']['file_name']; + + if (empty($config['socket']['max_len'])) { + throw new \DomainException("Максимальная длинна не найдена"); + } + + $this->maxLen = (int)$config['socket']['max_len']; + } +} diff --git a/src/Server.php b/src/Server.php new file mode 100644 index 000000000..6456867b8 --- /dev/null +++ b/src/Server.php @@ -0,0 +1,38 @@ +create(true); + $this->bind(); + $this->listen(); + } + + public function start(): void + { + echo "Старт сервера" . PHP_EOL; + $client = $this->accept(); + + $run = true; + while ($run) { + $message = $this->receive($client); + + if ($message === 'stop') { + socket_close($client); + $run = false; + } + + if ($message) { + echo "Пришло сообщение" . PHP_EOL; + echo $message . PHP_EOL; + } + } + + $this->close(); + } +} From 38c7050490491760b47d1156e0ee2ed5672ea690 Mon Sep 17 00:00:00 2001 From: Aliaksandr Harshkou Date: Sat, 17 Feb 2024 01:43:16 +0300 Subject: [PATCH 2/7] hw5 --- public/index.php | 1 - src/Chat.php | 2 -- src/Client.php | 1 - 3 files changed, 4 deletions(-) diff --git a/public/index.php b/public/index.php index 5a27d8d28..0750bf853 100644 --- a/public/index.php +++ b/public/index.php @@ -1,6 +1,5 @@ Date: Sat, 17 Feb 2024 01:44:54 +0300 Subject: [PATCH 3/7] hw5 --- src/Chat.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Chat.php b/src/Chat.php index d2b07edbb..b20e43580 100644 --- a/src/Chat.php +++ b/src/Chat.php @@ -11,8 +11,7 @@ abstract class Chat public function __construct( private readonly Config $config ) - { - } + {} public function create($clear = false): void { From 0b3a20db9a2dfa1cc773ddcd63803157689f1cfb Mon Sep 17 00:00:00 2001 From: Aliaksandr Harshkou Date: Sat, 17 Feb 2024 01:47:27 +0300 Subject: [PATCH 4/7] hw5 --- src/Chat.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Chat.php b/src/Chat.php index b20e43580..096135f48 100644 --- a/src/Chat.php +++ b/src/Chat.php @@ -8,10 +8,10 @@ abstract class Chat { private Socket $socket; - public function __construct( - private readonly Config $config - ) - {} + public function __construct(private readonly Config $config) + { + + } public function create($clear = false): void { From 8f411189a96a96629e62dff479ab264eabaa113a Mon Sep 17 00:00:00 2001 From: Aliaksandr Harshkou Date: Sat, 17 Feb 2024 01:48:12 +0300 Subject: [PATCH 5/7] hw5 --- src/Chat.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Chat.php b/src/Chat.php index 096135f48..2c437065c 100644 --- a/src/Chat.php +++ b/src/Chat.php @@ -10,7 +10,6 @@ abstract class Chat public function __construct(private readonly Config $config) { - } public function create($clear = false): void From 53cc0a02c0deb900d4c7a0bdbcaf6cbd55c23ae2 Mon Sep 17 00:00:00 2001 From: Aliaksandr Harshkou Date: Sun, 18 Feb 2024 17:22:42 +0300 Subject: [PATCH 6/7] hw5 --- src/Client.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Client.php b/src/Client.php index 326f000c6..85c66c153 100644 --- a/src/Client.php +++ b/src/Client.php @@ -13,9 +13,7 @@ public function start(): void $run = true; while ($run) { - echo 'Введите сообщение и нажмите Enter: ' . PHP_EOL; - - $message = readline(); + $message = readline('Введите сообщение и нажмите Enter: '); $this->send($message); if ($message === 'stop') { From 55cc3e3b52eac0a96ec2ba0b3c5add9e876938ff Mon Sep 17 00:00:00 2001 From: Aliaksandr Harshkou Date: Mon, 19 Feb 2024 19:57:35 +0300 Subject: [PATCH 7/7] hw5 --- public/index.php | 6 +++++- src/App.php | 8 +++++--- src/Client.php | 4 ++-- src/Server.php | 8 ++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/public/index.php b/public/index.php index 0750bf853..b7c31fab6 100644 --- a/public/index.php +++ b/public/index.php @@ -7,7 +7,11 @@ try { $app = new App(__DIR__ . '/../config/config.ini'); - $app->run($argv[1] ?? null); + $data = $app->run($argv[1] ?? null); + + foreach ($data as $message) { + echo $message; + } } catch (Exception $e) { echo "ERROR" . PHP_EOL; echo $e->getMessage() . PHP_EOL; diff --git a/src/App.php b/src/App.php index c515c2cea..34ef509f3 100644 --- a/src/App.php +++ b/src/App.php @@ -11,21 +11,23 @@ public function __construct(string $fileConfigName) $this->config = new Config($fileConfigName); } - public function run($arg): void + public function run($arg): \Generator { switch ($arg) { case 'server': $server = new Server($this->config); - $server->start(); + $data = $server->start(); break; case 'client': $client = new Client($this->config); - $client->start(); + $data = $client->start(); break; default: throw new \DomainException('Ошибка аргумента, server или client' . PHP_EOL); } + + return $data; } } diff --git a/src/Client.php b/src/Client.php index 85c66c153..ea2e98519 100644 --- a/src/Client.php +++ b/src/Client.php @@ -4,9 +4,9 @@ class Client extends Chat { - public function start(): void + public function start(): \Generator { - echo "Старт клиента" . PHP_EOL; + yield "Старт клиента" . PHP_EOL; $this->create(); $this->connect(); diff --git a/src/Server.php b/src/Server.php index 6456867b8..0dded72d4 100644 --- a/src/Server.php +++ b/src/Server.php @@ -13,9 +13,9 @@ public function __construct(Config $config) $this->listen(); } - public function start(): void + public function start(): \Generator { - echo "Старт сервера" . PHP_EOL; + yield "Старт сервера" . PHP_EOL; $client = $this->accept(); $run = true; @@ -28,8 +28,8 @@ public function start(): void } if ($message) { - echo "Пришло сообщение" . PHP_EOL; - echo $message . PHP_EOL; + yield "Пришло сообщение" . PHP_EOL; + yield $message . PHP_EOL; } }