Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .docker/php/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM php:7.4-fpm

WORKDIR /var/www/app

RUN apt-get update \
&& apt-get install -y \
git \
curl \
libzip-dev \
&& docker-php-ext-install -j$(nproc) \
sockets \
&& docker-php-ext-configure \
sockets --enable-sockets \
&& php -r "readfile('http://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.idea
vendor
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
# PHP2021
# PHP2021

https://otus.ru/lessons/razrabotchik-php/?utm_source=github&utm_medium=free&utm_campaign=otus


## HW-3
###Запуск сервера
![Запуск сервера](screenshots/up_server.png)

###Запуск клиента
![Запуск сервера](screenshots/up_client.png)

###Чат работает
![Запуск сервера](screenshots/chat_work.png)
14 changes: 14 additions & 0 deletions app
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/local/bin/php

<?php
require "vendor/autoload.php";

use Ivanboriev\SocketChat\App;

$app = new App();

try {
$app->run($argv[1]);
} catch (Exception $e) {
$app->error($e->getMessage());
}
16 changes: 16 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "ivanboriev/socket-chat",
"description": "Socket chat",
"type": "project",
"autoload": {

"psr-4": {
"Ivanboriev\\SocketChat\\": "src/"
}
},
"require": {
"php": ">=7.4",
"ext-json": "*",
"ext-sockets": "*"
}
}
32 changes: 32 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
version: '3'

services:
server:
build:
context: .docker/php
dockerfile: Dockerfile
image: ivanboriev/socket-chat
container_name: socket-server
volumes:
- .:/var/www/app

networks:
- chat-network


client:
build:
context: .docker/php
dockerfile: Dockerfile
image: ivanboriev/socket-chat
container_name: socket-client
volumes:
- .:/var/www/app

networks:
- chat-network


networks:
chat-network:
driver: bridge
Binary file added screenshots/chat_work.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/up_client.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/up_server.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 51 additions & 0 deletions src/App.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace Ivanboriev\SocketChat;

use Exception;
use Ivanboriev\SocketChat\Exceptions\UnknownCommandException;
use Ivanboriev\SocketChat\Server\Server;
use Ivanboriev\SocketChat\Client\Client;
use Ivanboriev\SocketChat\Traits\HasMessage;

class App
{
use HasMessage;

private array $config;

public function __construct()
{
$this->config = parse_ini_file('config.ini');
}

/**
* @throws Exception
*/
public function run($type): void
{
switch ($type) {
case 'server':
$this->runServer();
break;
case 'client' :
$this->runClient();
break;
default:
throw new UnknownCommandException($type . ' - неизвестная команда');
}
}


private function runServer()
{
(new Server)->run($this->config);
}


private function runClient()
{
(new Client)->run($this->config);
}

}
103 changes: 103 additions & 0 deletions src/Client/Client.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace Ivanboriev\SocketChat\Client;

use Ivanboriev\SocketChat\Exceptions\SocketBindException;
use Ivanboriev\SocketChat\Exceptions\SocketListenException;
use Ivanboriev\SocketChat\Exceptions\SocketReadException;
use Ivanboriev\SocketChat\Exceptions\SocketWriteException;
use Ivanboriev\SocketChat\Traits\HasMessage;

class Client
{
use HasMessage;

/** @var false|resource|\Socket */
private $socket;

/** @var false|resource|\Socket */
private $connection;

private array $config;

/**
* @throws SocketListenException
* @throws SocketBindException
*/
public function run(array $config): void
{
$this->config = $config;

$this->initConnection();
$this->sendMessages();
$this->closeConnection();
}

/**
* @throws SocketBindException
* @throws \Exception
*/
private function initConnection()
{
$this->info("Поднимаю соединение...");

$this->socket = socket_create(AF_UNIX, SOCK_STREAM, 0);

if (!socket_connect($this->socket, $this->config['SOCKET_PATH'])) {
throw new SocketBindException;
}

$this->info('Соединение установлено, введите сообщение...');

}

private function sendMessages()
{
do {
$this->send('Введите сообщение: ');

try {
$message = trim(fgets(STDIN));

$this->sendMessage($message);

$this->send($this->getMessage());
} catch (\Exception $e) {
$this->error($e->getMessage());
}


} while ($message !== $this->config['EXIT_MSG']);

}

/**
* @throws \Exception
*/
private function sendMessage(string $message): void
{
if (socket_write($this->socket, $message, strlen($message)) === false) {
throw new SocketWriteException;
}
}

/**
* @throws \Exception
*/
private function getMessage(): string
{
$message = socket_read($this->socket, 1024);
if ($message === false) {
throw new SocketReadException;
}

return "Ответ от сервера: " . $message;
}

private function closeConnection()
{
$this->info("Закрываем соединение...");
socket_close($this->socket);
$this->info("Соединение закрыто");
}
}
7 changes: 7 additions & 0 deletions src/Exceptions/ErrorStartingServerException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
namespace Ivanboriev\SocketChat\Exceptions;

class ErrorStartingServerException extends \Exception
{
protected $message = "Ошибка при запуске сервера";
}
7 changes: 7 additions & 0 deletions src/Exceptions/SocketBindException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php
namespace Ivanboriev\SocketChat\Exceptions;

class SocketBindException extends \Exception
{
protected $message = "Не удалось установить соединение с сокетом";
}
8 changes: 8 additions & 0 deletions src/Exceptions/SocketListenException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Ivanboriev\SocketChat\Exceptions;


class SocketListenException extends \Exception
{
protected $message = "Невозможно прослушать сокет";
}
8 changes: 8 additions & 0 deletions src/Exceptions/SocketReadException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Ivanboriev\SocketChat\Exceptions;


class SocketReadException extends \Exception
{
protected $message = "Невозможно прочитать сокет";
}
8 changes: 8 additions & 0 deletions src/Exceptions/SocketWriteException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Ivanboriev\SocketChat\Exceptions;


class SocketWriteException extends \Exception
{
protected $message = "Невозможно записать в сокет";
}
8 changes: 8 additions & 0 deletions src/Exceptions/UnknownCommandException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Ivanboriev\SocketChat\Exceptions;


class UnknownCommandException extends \Exception
{

}
Loading