This commit is contained in:
2021-08-12 12:40:06 +08:00
parent 39af292171
commit 9a6c7b835b
19 changed files with 655 additions and 29 deletions
+16
View File
@@ -0,0 +1,16 @@
<?php
namespace Server\Abstracts;
use Annotation\Inject;
use Kiri\Events\EventDispatch;
trait EventDispatchHelper
{
/** @var EventDispatch */
#[Inject(EventDispatch::class)]
public EventDispatch $eventDispatch;
}
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace Server\Abstracts;
use Annotation\Inject;
use HttpServer\Route\Router;
use Kiri\Abstracts\Config;
use Kiri\Events\EventDispatch;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use ReflectionException;
use Server\Constrict\Response as CResponse;
use Server\Constrict\ResponseEmitter;
use Server\ExceptionHandlerDispatcher;
use Server\ExceptionHandlerInterface;
use Server\ListenerHelper;
use Server\SInterface\OnRequest;
/**
*
*/
abstract class Http implements OnRequest
{
use EventDispatchHelper;
use ResponseHelper;
/** @var Router|mixed */
#[Inject('router')]
public Router $router;
/**
* @var ExceptionHandlerInterface
*/
public ExceptionHandlerInterface $exceptionHandler;
/**
* @throws ReflectionException
* @throws ConfigException
* @throws NotFindClassException
*/
public function init()
{
$exceptionHandler = Config::get('exception.http', ExceptionHandlerDispatcher::class);
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
$exceptionHandler = ExceptionHandlerDispatcher::class;
}
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace Server\Abstracts;
use Annotation\Inject;
use Server\Constrict\Response as CResponse;
use Server\Constrict\ResponseEmitter;
/**
*
*/
trait ResponseHelper
{
/** @var CResponse|mixed */
#[Inject(CResponse::class)]
public CResponse $response;
/** @var ResponseEmitter */
#[Inject(ResponseEmitter::class)]
public ResponseEmitter $responseEmitter;
}
+42
View File
@@ -0,0 +1,42 @@
<?php
namespace Server\Abstracts;
use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use ReflectionException;
use Server\ExceptionHandlerDispatcher;
use Server\ExceptionHandlerInterface;
use Server\SInterface\OnReceive;
abstract class Tcp implements OnReceive
{
use EventDispatchHelper;
use ResponseHelper;
/**
* @var ExceptionHandlerInterface
*/
public ExceptionHandlerInterface $exceptionHandler;
/**
* @throws ReflectionException
* @throws ConfigException
* @throws NotFindClassException
*/
public function init()
{
$exceptionHandler = Config::get('exception.tcp', ExceptionHandlerDispatcher::class);
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
$exceptionHandler = ExceptionHandlerDispatcher::class;
}
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
namespace Server\Abstracts;
use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use ReflectionException;
use Server\ExceptionHandlerDispatcher;
use Server\ExceptionHandlerInterface;
use Server\SInterface\OnPacket;
use Server\SInterface\OnReceive;
abstract class Udp implements OnPacket
{
use EventDispatchHelper;
use ResponseHelper;
/**
* @var ExceptionHandlerInterface
*/
public ExceptionHandlerInterface $exceptionHandler;
/**
* @throws ReflectionException
* @throws ConfigException
* @throws NotFindClassException
*/
public function init()
{
$exceptionHandler = Config::get('exception.udp', ExceptionHandlerDispatcher::class);
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
$exceptionHandler = ExceptionHandlerDispatcher::class;
}
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php
namespace Server\Abstracts;
use Exception;
use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use ReflectionException;
use Server\ExceptionHandlerDispatcher;
use Server\ExceptionHandlerInterface;
use Server\SInterface\OnClose;
use Server\SInterface\OnHandshake;
use Server\SInterface\OnMessage;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Server;
/**
*
*/
abstract class Websocket implements OnHandshake, OnMessage, OnClose
{
use EventDispatchHelper;
use ResponseHelper;
/**
* @var ExceptionHandlerInterface
*/
public ExceptionHandlerInterface $exceptionHandler;
/**
* @throws ReflectionException
* @throws ConfigException
* @throws NotFindClassException
*/
public function init()
{
$exceptionHandler = Config::get('exception.websocket', ExceptionHandlerDispatcher::class);
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
$exceptionHandler = ExceptionHandlerDispatcher::class;
}
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
}
/**
* @param Request $request
* @param Response $response
* @throws Exception
*/
public function onHandshake(Request $request, Response $response): void
{
// TODO: Implement OnHandshake() method.
/** @var \Swoole\WebSocket\Server $server */
$secWebSocketKey = $request->header['sec-websocket-key'];
$patten = '#^[+/0-9A-Za-z]{21}[AQgw]==$#';
if (0 === preg_match($patten, $secWebSocketKey) || 16 !== strlen(base64_decode($secWebSocketKey))) {
throw new Exception('protocol error.', 500);
}
$key = base64_encode(sha1($request->header['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', TRUE));
$headers = [
'Upgrade' => 'websocket',
'Connection' => 'Upgrade',
'Sec-websocket-Accept' => $key,
'Sec-websocket-Version' => '13',
];
if (isset($request->header['sec-websocket-protocol'])) {
$headers['Sec-websocket-Protocol'] = $request->header['sec-websocket-protocol'];
}
foreach ($headers as $key => $val) {
$response->setHeader($key, $val);
}
}
}
-1
View File
@@ -22,7 +22,6 @@ trait ListenerHelper
* @param array $events
* @param array|Closure $default
* @return mixed
* @throws NotFindClassException
* @throws ReflectionException
*/
protected static function callback(string $name, array $events, array|Closure $default): mixed
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace Server\SInterface;
use Swoole\Server;
/**
*
*/
interface OnClose
{
/**
* @param Server $server
* @param int $fd
*/
public function onClose(Server $server, int $fd): void;
/**
* @param Server $server
* @param int $fd
*/
public function onDisconnect(Server $server, int $fd): void;
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Server\SInterface;
use Swoole\Server;
interface OnConnect
{
/**
* @param Server $server
* @param int $fd
* @return void
*/
public function onConnect(Server $server, int $fd): void;
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace Server\SInterface;
use Swoole\Http\Request;
use Swoole\Http\Response;
/**
*
*/
interface OnHandshake
{
/**
* @param Request $request
* @param Response $response
*/
public function OnHandshake(Request $request, Response $response): void;
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace Server\SInterface;
use Swoole\Server;
use Swoole\WebSocket\Frame;
interface OnMessage
{
/**
* @param Server $server
* @param Frame $frame
* @return void
*/
public function OnMessage(Server $server, Frame $frame): void;
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace Server\SInterface;
use Server\Abstracts\Server;
interface OnPacket
{
/**
* @param Server $server
* @param string $data
* @param array $clientInfo
* @return mixed
*/
public function onPacket(Server $server, string $data, array $clientInfo): void;
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace Server\SInterface;
use Swoole\Server;
/**
*
*/
interface OnReceive
{
/**
* @param Server $server
* @param int $fd
* @param int $reactor_id
* @param string $data
* @return void
*/
public function onReceive(Server $server, int $fd, int $reactor_id, string $data): void;
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Server\SInterface;
use Swoole\Http\Request;
use Swoole\Http\Response;
interface OnRequest
{
/**
* @param Request $request
* @param Response $response
*/
public function onRequest(Request $request, Response $response): void;
}
+22 -28
View File
@@ -4,15 +4,15 @@ namespace Server;
use Closure;
use Exception;
use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use ReflectionException;
use Server\Manager\OnPipeMessage;
use Server\SInterface\CustomProcess;
use Server\SInterface\TaskExecute;
use Server\Task\OnServerTask;
use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use Swoole\Http\Server as HServer;
use Swoole\Process;
use Swoole\Server;
@@ -240,14 +240,7 @@ class ServerManager extends Abstracts\Server
throw new Exception("The port is already in use[$host::$port]");
}
$this->ports[$port]->set($settings['settings'] ?? []);
$reflect = match ($type) {
Constant::SERVER_TYPE_TCP => Kiri::getDi()->newObject(TCPServerListener::class),
Constant::SERVER_TYPE_UDP => Kiri::getDi()->newObject(UDPServerListener::class),
Constant::SERVER_TYPE_HTTP => Kiri::getDi()->newObject(HTTPServerListener::class),
Constant::SERVER_TYPE_WEBSOCKET => Kiri::getDi()->newObject(WebSocketServerListener::class),
default => throw new Exception(''),
};
$reflect->bindCallback($this->ports[$port], $settings['events'] ?? []);
$this->addServiceEvents($settings['events'] ?? [], $this->ports[$port]);
}
@@ -335,22 +328,23 @@ class ServerManager extends Abstracts\Server
if (($this->server->setting['task_worker_num'] ?? 0) > 0) {
$this->addTaskListener($settings['events']);
}
if ($type === Constant::SERVER_TYPE_WEBSOCKET) {
/** @var WebSocketServerListener $reflect */
$reflect = $this->getNewInstance(WebSocketServerListener::class);
$reflect->bindCallback($this->server, $settings);
} else if ($type === Constant::SERVER_TYPE_UDP) {
/** @var UDPServerListener $reflect */
$reflect = $this->getNewInstance(UDPServerListener::class);
$reflect->bindCallback($this->server, $settings);
} else if ($type === Constant::SERVER_TYPE_HTTP) {
/** @var HTTPServerListener $reflect */
$reflect = $this->getNewInstance(HTTPServerListener::class);
$reflect->bindCallback($this->server, $settings);
} else {
/** @var TCPServerListener $reflect */
$reflect = $this->getNewInstance(TCPServerListener::class);
$reflect->bindCallback($this->server, $settings);
$this->addServiceEvents($settings['events'] ?? [], $this->server);
}
/**
* @param array $events
* @param Server $server
* @throws NotFindClassException
* @throws ReflectionException
*/
private function addServiceEvents(array $events, Server $server)
{
foreach ($events as $name => $event) {
if (is_array($event) && is_string($event)) {
$callback[0] = $this->getNewInstance($event[0]);
}
$server->on($name, $event);
}
}
+71
View File
@@ -0,0 +1,71 @@
<?php
namespace Server\Service;
use Exception;
use HttpServer\Exception\RequestException;
use HttpServer\Route\Node;
use Kiri\Exception\NotFindClassException;
use ReflectionException;
use Server\Events\OnAfterRequest;
use Server\ResponseInterface;
use Server\SInterface\OnClose;
use Swoole\Error;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Server;
/**
*
*/
class Http extends \Server\Abstracts\Http implements OnClose
{
/**
* @param Request $request
* @param Response $response
* @throws NotFindClassException
* @throws ReflectionException
*/
public function onRequest(Request $request, Response $response): void
{
// TODO: Implement onRequest() method.
try {
$node = $this->router->Branch_search(\Server\Constrict\Request::create($request));
if (!($node instanceof Node)) {
throw new RequestException('<h2>HTTP 404 Not Found</h2><hr><i>Powered by Swoole</i>', 404);
}
if (!(($responseData = $node->dispatch()) instanceof ResponseInterface)) {
$responseData = $this->response->setContent($responseData)->setStatusCode(200);
}
} catch (Error | \Throwable $exception) {
$responseData = $this->exceptionHandler->emit($exception, $this->response);
} finally {
$this->responseEmitter->sender($response, $responseData);
$this->eventDispatch->dispatch(new OnAfterRequest());
}
}
/**
* @param Server $server
* @param int $fd
* @throws Exception
*/
public function onDisconnect(Server $server, int $fd): void
{
}
/**
* @param Server $server
* @param int $fd
* @throws Exception
*/
public function onClose(Server $server, int $fd): void
{
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace Server\Service;
use Server\SInterface\OnClose;
use Server\SInterface\OnConnect;
use Swoole\Server;
/**
*
*/
class Tcp extends \Server\Abstracts\Tcp implements OnConnect, OnClose
{
/**
* @param Server $server
* @param int $fd
*/
public function onConnect(Server $server, int $fd): void
{
// TODO: Implement onConnect() method.
}
/**
* @param Server $server
* @param int $fd
* @param int $reactor_id
* @param string $data
*/
public function onReceive(Server $server, int $fd, int $reactor_id, string $data): void
{
// TODO: Implement onReceive() method.
}
/**
* @param Server $server
* @param int $fd
*/
public function onClose(Server $server, int $fd): void
{
// TODO: Implement onClose() method.
}
/**
* @param Server $server
* @param int $fd
*/
public function onDisconnect(Server $server, int $fd): void
{
// TODO: Implement onDisconnect() method.
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace Server\Service;
use Server\Abstracts\Server;
/**
*
*/
class Udp extends \Server\Abstracts\Udp
{
/**
* @param Server $server
* @param string $data
* @param array $clientInfo
*/
public function onPacket(Server $server, string $data, array $clientInfo): void
{
// TODO: Implement onPacket() method.
}
}
+62
View File
@@ -0,0 +1,62 @@
<?php
namespace Server\Service;
use Exception;
use Server\SInterface\OnRequest;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Swoole\Server;
use Swoole\WebSocket\Frame;
/**
*
*/
class WebSocket extends \Server\Abstracts\Websocket
{
/**
* @param Request $request
* @param Response $response
* @throws Exception
*/
public function onHandshake(Request $request, Response $response): void
{
parent::onHandshake($request, $response); // TODO: Change the autogenerated stub
$response->status(101);
$response->end();
}
/**
* @param Server $server
* @param Frame $frame
*/
public function onMessage(Server $server, Frame $frame): void
{
// TODO: Implement OnMessage() method.
}
/**
* @param Server $server
* @param int $fd
*/
public function onClose(Server $server, int $fd): void
{
// TODO: Implement OnClose() method.
}
/**
* @param Server $server
* @param int $fd
*/
public function onDisconnect(Server $server, int $fd): void
{
// TODO: Implement OnDisconnect() method.
}
}