diff --git a/README.md b/README.md index 7b39def..6597d9a 100644 --- a/README.md +++ b/README.md @@ -39,4 +39,44 @@ var_dump( #### Request::setQuery #### Request::getQuery #### Request::getOptions -#### Request::setOptions \ No newline at end of file +#### Request::setOptions + +## Server + +Build interactive server instance to listen Nex protocol connections! + +``` php +$server = new \Yggverse\Nex\Server; +``` + +Provide optional `host`, `port` and `size` arguments in constructor or use available setters after object initiation. + +``` php +$server = new \Yggverse\Nex\Server('127.0.0.1', 1915); +``` + +#### Server::setHost +#### Server::getHost +#### Server::setPort +#### Server::getPort + +#### Server::start + +Run server object using this method. + +Define handler function as the argument to process application logic dependent of client request. + +``` php +$server->start( + function ( + string $request, + string $connect + ) { + printf( + 'connection: %s request: %s', + $connect, + $request + ); + } +); +``` diff --git a/src/Server.php b/src/Server.php new file mode 100644 index 0000000..4b84947 --- /dev/null +++ b/src/Server.php @@ -0,0 +1,128 @@ +setHost( + $host + ); + + $this->setPort( + $port + ); + + $this->setSize( + $size + ); + } + + 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 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 + ); + + while ($socket) + { + $incoming = stream_socket_accept( + $socket, -1, $connect + ); + + stream_set_blocking( + $incoming, + true + ); + + $request = fread( + $incoming, + $this->_size + ); + + stream_set_blocking( + $incoming, + false + ); + + if ($handler) + { + $response = call_user_func( + $handler, + $request, + $connect + ); + } + + fclose( + $incoming + ); + } + } +}