From 738892bbcd00314eefc49f2c1316101f5572b090 Mon Sep 17 00:00:00 2001 From: Rudolf Medvedev Date: Fri, 15 Sep 2023 21:39:38 +0300 Subject: [PATCH 1/2] HW6 --- .gitignore | 1 + app.php | 13 ++ composer.json | 19 ++ composer.lock | 361 +++++++++++++++++++++++++++++++++ config.ini | 1 + docker-compose.yaml | 33 +++ docker/php/Dockerfile | 31 +++ src/Application.php | 18 ++ src/Libs/Config.php | 25 +++ src/Libs/Dispatching.php | 19 ++ src/Services/ClientService.php | 40 ++++ src/Services/ServerService.php | 41 ++++ 12 files changed, 602 insertions(+) create mode 100644 .gitignore create mode 100644 app.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config.ini create mode 100644 docker-compose.yaml create mode 100644 docker/php/Dockerfile create mode 100644 src/Application.php create mode 100644 src/Libs/Config.php create mode 100644 src/Libs/Dispatching.php create mode 100644 src/Services/ClientService.php create mode 100644 src/Services/ServerService.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..57872d0f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor/ diff --git a/app.php b/app.php new file mode 100644 index 000000000..908450c47 --- /dev/null +++ b/app.php @@ -0,0 +1,13 @@ +run($argv); +} +catch (Exception $exception) { + throw new \RuntimeException($exception->getMessage()); +} \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..04e3f627c --- /dev/null +++ b/composer.json @@ -0,0 +1,19 @@ +{ + "name": "rofflexor/hw6", + "type": "project", + "license": "mti", + "autoload": { + "psr-4": { + "Rofflexor\\Hw\\": "src/" + } + }, + "authors": [ + { + "name": "Rudolf Medvedev", + "email": "rof@andia.ru" + } + ], + "require": { + "dazzle-php/socket": "^0.4.1" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 000000000..85d42f7ca --- /dev/null +++ b/composer.lock @@ -0,0 +1,361 @@ +{ + "_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": "e172592f27b88d265956fd2226920eab", + "packages": [ + { + "name": "dazzle-php/socket", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/dazzle-php/socket.git", + "reference": "c32cea9c8794a5b233a805f799634e6c99ee47d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dazzle-php/socket/zipball/c32cea9c8794a5b233a805f799634e6c99ee47d0", + "reference": "c32cea9c8794a5b233a805f799634e6c99ee47d0", + "shasum": "" + }, + "require": { + "kraken-php/event": "0.4.*", + "kraken-php/loop": "0.4.*", + "kraken-php/stream": "0.4.*", + "kraken-php/throwable": "0.4.*", + "php": ">=5.6.7" + }, + "suggest": { + "ext-zmq": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5-dev" + } + }, + "autoload": { + "psr-4": { + "Kraken\\Ipc\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kamil Jamroz" + } + ], + "description": "Kraken Framework Ipc Component.", + "homepage": "http://kraken-php.com", + "keywords": [ + "agent-model", + "ipc", + "kraken", + "kraken-php", + "message-driven", + "service-oriented", + "soa", + "zeromq", + "zmq" + ], + "support": { + "issues": "https://github.com/kraken-php/framework/issues", + "source": "https://github.com/kraken-php/framework" + }, + "time": "2017-05-11T20:36:41+00:00" + }, + { + "name": "kraken-php/event", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/kraken-php/event.git", + "reference": "2169388cfea22a408e9d0e3e4b62d0e590e22d29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kraken-php/event/zipball/2169388cfea22a408e9d0e3e4b62d0e590e22d29", + "reference": "2169388cfea22a408e9d0e3e4b62d0e590e22d29", + "shasum": "" + }, + "require": { + "kraken-php/loop": "0.4.*", + "php": ">=5.6.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5-dev" + } + }, + "autoload": { + "psr-4": { + "Kraken\\Event\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kamil Jamroz" + } + ], + "description": "Kraken Framework Event Component.", + "homepage": "http://kraken-php.com", + "keywords": [ + "emitter", + "event", + "event emitter", + "event-driven", + "kraken", + "kraken-php" + ], + "support": { + "issues": "https://github.com/kraken-php/framework/issues", + "source": "https://github.com/kraken-php/framework" + }, + "time": "2017-06-17T17:15:26+00:00" + }, + { + "name": "kraken-php/loop", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/kraken-php/loop.git", + "reference": "57878a092b03fc80aeccfb94b8c457569186ac5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kraken-php/loop/zipball/57878a092b03fc80aeccfb94b8c457569186ac5f", + "reference": "57878a092b03fc80aeccfb94b8c457569186ac5f", + "shasum": "" + }, + "require": { + "kraken-php/util": "0.4.*", + "php": ">=5.6.7" + }, + "suggest": { + "ext-event": "~1.0", + "ext-libev": "*", + "ext-libevent": ">=0.1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5-dev" + } + }, + "autoload": { + "psr-4": { + "Kraken\\Loop\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kamil Jamroz" + } + ], + "description": "Kraken Framework Loop Component.", + "homepage": "http://kraken-php.com", + "keywords": [ + "async", + "asynchronous", + "event", + "event-loop", + "kraken", + "kraken-php", + "libev", + "libevent", + "loop" + ], + "support": { + "issues": "https://github.com/kraken-php/framework/issues", + "source": "https://github.com/kraken-php/framework" + }, + "time": "2017-05-11T20:36:41+00:00" + }, + { + "name": "kraken-php/stream", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/kraken-php/stream.git", + "reference": "1940ecfc3d77384eeeb2c633be6ff7067917bbd5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kraken-php/stream/zipball/1940ecfc3d77384eeeb2c633be6ff7067917bbd5", + "reference": "1940ecfc3d77384eeeb2c633be6ff7067917bbd5", + "shasum": "" + }, + "require": { + "kraken-php/event": "0.4.*", + "kraken-php/loop": "0.4.*", + "kraken-php/throwable": "0.4.*", + "kraken-php/util": "0.4.*", + "php": ">=5.6.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5-dev" + } + }, + "autoload": { + "psr-4": { + "Kraken\\Stream\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kamil Jamroz" + } + ], + "description": "Asynchronous Stream Library.", + "homepage": "http://kraken-php.com", + "keywords": [ + "async", + "asynchronous", + "kraken", + "kraken-php", + "stream" + ], + "support": { + "issues": "https://github.com/kraken-php/framework/issues", + "source": "https://github.com/kraken-php/framework" + }, + "time": "2017-05-11T20:36:41+00:00" + }, + { + "name": "kraken-php/throwable", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/kraken-php/throwable.git", + "reference": "add591e895aafe88a81fd47a772e272bfd750652" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kraken-php/throwable/zipball/add591e895aafe88a81fd47a772e272bfd750652", + "reference": "add591e895aafe88a81fd47a772e272bfd750652", + "shasum": "" + }, + "require": { + "php": ">=5.6.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5-dev" + } + }, + "autoload": { + "psr-4": { + "Kraken\\Throwable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kamil Jamroz" + } + ], + "description": "Kraken Framework Throwable Component.", + "homepage": "http://kraken-php.com", + "keywords": [ + "error", + "exception", + "kraken", + "kraken-php", + "throwable" + ], + "support": { + "issues": "https://github.com/kraken-php/framework/issues", + "source": "https://github.com/kraken-php/framework" + }, + "time": "2017-05-11T20:36:41+00:00" + }, + { + "name": "kraken-php/util", + "version": "v0.4.1", + "source": { + "type": "git", + "url": "https://github.com/kraken-php/util.git", + "reference": "99e15ce04fd90f71421daeb31bc081dcbabed5b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kraken-php/util/zipball/99e15ce04fd90f71421daeb31bc081dcbabed5b1", + "reference": "99e15ce04fd90f71421daeb31bc081dcbabed5b1", + "shasum": "" + }, + "require": { + "kraken-php/throwable": "0.4.*", + "php": ">=5.6.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5-dev" + } + }, + "autoload": { + "psr-4": { + "Kraken\\Util\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kamil Jamroz" + } + ], + "description": "Kraken Framework Util Component.", + "homepage": "http://kraken-php.com", + "keywords": [ + "design", + "kraken", + "kraken-php", + "pattern", + "support", + "util", + "utility" + ], + "support": { + "issues": "https://github.com/kraken-php/framework/issues", + "source": "https://github.com/kraken-php/framework" + }, + "time": "2017-05-11T20:36:41+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/config.ini b/config.ini new file mode 100644 index 000000000..8708ec2b0 --- /dev/null +++ b/config.ini @@ -0,0 +1 @@ +socket_path=shared/chat_socket.sock \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 000000000..dededbe59 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,33 @@ +version: '3.9' + +services: + client: + build: + context: . + dockerfile: ./docker/php/Dockerfile + image: digitalocean.com/php + container_name: chat_client + restart: unless-stopped + tty: true + working_dir: /var/www/ + volumes: + - ./:/var/www/ + - shared:/shared + + server: + build: + context: . + dockerfile: ./docker/php/Dockerfile + image: digitalocean.com/php + container_name: chat_server + restart: unless-stopped + tty: true + working_dir: /var/www/ + volumes: + - ./:/var/www/ + - shared:/shared + depends_on: + - client + +volumes: + shared: {} diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 000000000..a8cdb3e82 --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,31 @@ +FROM php:8.2-fpm + +WORKDIR /var/www + +RUN apt-get update && apt-get install -y \ + libfreetype6-dev \ + libjpeg62-turbo-dev \ + libmcrypt-dev \ + libpng-dev \ + zlib1g-dev \ + libxml2-dev \ + libzip-dev \ + libonig-dev \ + graphviz \ + libpq-dev \ + libmemcached-dev \ + libmemcached11 \ + && docker-php-ext-configure gd \ + && docker-php-ext-install -j$(nproc) gd \ + && docker-php-ext-install zip \ + && docker-php-ext-install sockets \ + && docker-php-source delete \ + && curl -sS https://getcomposer.org/installer | php -- \ + --install-dir=/usr/local/bin --filename=composer \ + && pecl install redis \ + && docker-php-ext-enable redis \ + && pecl install apcu \ + && pecl install memcached + +EXPOSE 9000 +CMD ["php-fpm"] diff --git a/src/Application.php b/src/Application.php new file mode 100644 index 000000000..6b8f45bdb --- /dev/null +++ b/src/Application.php @@ -0,0 +1,18 @@ +dispatch($argv)->start(); + } + +} \ No newline at end of file diff --git a/src/Libs/Config.php b/src/Libs/Config.php new file mode 100644 index 000000000..4e0f0ef21 --- /dev/null +++ b/src/Libs/Config.php @@ -0,0 +1,25 @@ +configPath)) { + throw new \InvalidArgumentException('Could not upload configuration'); + } + $this->config = parse_ini_file($this->configPath); + } + + public function getSocketPath() { + return array_key_exists('socket_path', $this->config) + ? $this->config['socket_path'] + : throw new \InvalidArgumentException('Config socket_path must be defined'); + } +} \ No newline at end of file diff --git a/src/Libs/Dispatching.php b/src/Libs/Dispatching.php new file mode 100644 index 000000000..4b091d0f2 --- /dev/null +++ b/src/Libs/Dispatching.php @@ -0,0 +1,19 @@ +loop = new Loop(new SelectLoop()); + } + + /** + * @throws InstantiationException + */ + public function start() { + $socket = new Socket('unix://'.(new Config())->getSocketPath(), $this->loop); + $socket->on('close', function() { + printf("Server has closed the connection!\n"); + $this->loop->stop(); + }); + + $this->loop->addPeriodicTimer(1, function() use($socket) { + $input = rtrim(fgets(STDIN)); + if(!empty($input)) { + $socket->write($input); + } + }); + + $this->loop->start(); + } + +} \ No newline at end of file diff --git a/src/Services/ServerService.php b/src/Services/ServerService.php new file mode 100644 index 000000000..36f5d003e --- /dev/null +++ b/src/Services/ServerService.php @@ -0,0 +1,41 @@ +loop = new Loop(new SelectLoop()); + } + + /** + * @throws InstantiationException + */ + public function start() { + $server = new SocketListener('unix://'.(new Config())->getSocketPath(), $this->loop); + $server->on('connect', function($server, SocketInterface $client) { + printf("New connection #%s from %s!\n", $res = $client->getResourceId(), $client->getLocalAddress()); + + $client->on('data', function($client, $data) use(&$buffer) { + printf("Received message=\"%s\"\n", $data); + }); + $client->on('close', function() use($res) { + printf("Closed connection #$res\n"); + }); + }); + $server->start(); + $this->loop->start(); + } + +} \ No newline at end of file From 2f0f1e99e86c62762fac1f6080d32e6ada1e95d1 Mon Sep 17 00:00:00 2001 From: Rudolf Medvedev Date: Fri, 15 Sep 2023 22:51:54 +0300 Subject: [PATCH 2/2] answer --- src/Services/ClientService.php | 8 ++++---- src/Services/ServerService.php | 11 ++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Services/ClientService.php b/src/Services/ClientService.php index 385e8dad4..5211ce077 100644 --- a/src/Services/ClientService.php +++ b/src/Services/ClientService.php @@ -22,15 +22,15 @@ public function __construct() */ public function start() { $socket = new Socket('unix://'.(new Config())->getSocketPath(), $this->loop); - $socket->on('close', function() { - printf("Server has closed the connection!\n"); - $this->loop->stop(); - }); + $socket->on('data', function ($socket, $data) { + printf("%s\n", $data); + }); $this->loop->addPeriodicTimer(1, function() use($socket) { $input = rtrim(fgets(STDIN)); if(!empty($input)) { $socket->write($input); + $socket->read(); } }); diff --git a/src/Services/ServerService.php b/src/Services/ServerService.php index 36f5d003e..a0e88e54e 100644 --- a/src/Services/ServerService.php +++ b/src/Services/ServerService.php @@ -25,16 +25,13 @@ public function __construct() public function start() { $server = new SocketListener('unix://'.(new Config())->getSocketPath(), $this->loop); $server->on('connect', function($server, SocketInterface $client) { - printf("New connection #%s from %s!\n", $res = $client->getResourceId(), $client->getLocalAddress()); - $client->on('data', function($client, $data) use(&$buffer) { - printf("Received message=\"%s\"\n", $data); - }); - $client->on('close', function() use($res) { - printf("Closed connection #$res\n"); + $client->write("Received message=$data\n"); }); }); - $server->start(); + $this->loop->onStart(function() use($server) { + $server->start(); + }); $this->loop->start(); }