From 0197b3629780d50dc3417f00fa79b2c4ad1abe63 Mon Sep 17 00:00:00 2001 From: yggverse Date: Wed, 24 Apr 2024 22:59:50 +0300 Subject: [PATCH] implement server class --- README.md | 9 ++- src/Server.php | 184 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 src/Server.php diff --git a/README.md b/README.md index 7cebc55..c146d00 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ PHP 8 / Composer Library for NPS Protocol Unlike Titan for Gemini, NPS is the satellite for Nex protocol (see also [nex-php](https://github.com/YGGverse/nex-php))\ -it listen for dot in line to signal the package ending. +it listen for single dot in line to signal the package ending. ## Specification @@ -52,9 +52,12 @@ $server->start( string $connect ) { printf( - 'connection: %s request: %s content: %s', + 'connection: %s request: %s', $connect, - $request, + $request + ); + + var_dump( $content ); } diff --git a/src/Server.php b/src/Server.php new file mode 100644 index 0000000..a32dc45 --- /dev/null +++ b/src/Server.php @@ -0,0 +1,184 @@ +setHost( + $host + ); + + $this->setPort( + $port + ); + + $this->setSize( + $size + ); + + $this->setLive( + $live + ); + } + + public function getHost(): string + { + return $this->_host; + } + + public function setHost( + string $value + ): void + { + if (false === filter_var($value, FILTER_VALIDATE_IP)) + { + throw new \Exception(); + } + + if (strpos($value, ':')) + { + $value = sprintf( + '[%s]', + $value + ); + } + + $this->_host = $value; + } + + public function getPort(): int + { + return $this->_port; + } + + public function setPort( + int $value + ): void + { + $this->_port = $value; + } + + public function getSize(): int + { + return $this->_size; + } + + public function setSize( + int $value + ): void + { + $this->_size = $value; + } + + public function getLive(): bool + { + return $this->_live; + } + + public function setLive( + bool $value + ): void + { + $this->_live = $value; + } + + public function start( + ?callable $handler = null + ): void + { + $socket = stream_socket_server( + sprintf( + 'tcp://%s:%d', + $this->_host, + $this->_port + ), + $error, + $message, + STREAM_SERVER_BIND | STREAM_SERVER_LISTEN + ); + + do + { + if (!$this->_live) + { + fclose( + $socket + ); + + break; + } + + $incoming = stream_socket_accept( + $socket, -1, $connect + ); + + stream_set_blocking( + $incoming, + true + ); + + $request = fread( + $incoming, + $this->_size + ); + + $content = ''; + + do + { + $line = trim( + fread( + $incoming, + $this->_size + ) + ); + + if ($line == '.') + { + break; + } + + $content .= $line; + + } while ($this->_live); + + stream_set_blocking( + $incoming, + false + ); + + fclose( + $incoming + ); + + if ($handler) + { + $response = call_user_func( + $handler, + $content, + $request, + $connect + ); + } + + } while ($this->_live); + } + + public function stop(): void + { + $this->setLive( + false + ); + } +}