This commit is contained in:
2021-06-25 11:20:38 +08:00
parent fbe83aff27
commit aa72ac2eb9
11 changed files with 261 additions and 430 deletions
+3 -10
View File
@@ -7,10 +7,6 @@ namespace Annotation\Route;
use Annotation\Attribute; use Annotation\Attribute;
use Exception; use Exception;
use HttpServer\Route\Router; use HttpServer\Route\Router;
use ReflectionException;
use Snowflake\Exception\ComponentException;
use Snowflake\Exception\ConfigException;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake; use Snowflake\Snowflake;
/** /**
@@ -30,17 +26,14 @@ use Snowflake\Snowflake;
* @param string|null $uri * @param string|null $uri
* @param string $version * @param string $version
*/ */
public function __construct( public function __construct(public string $event, public ?string $uri = null, public string $version = 'v.1.0')
public string $event,
public ?string $uri = null,
public string $version = 'v.1.0'
)
{ {
} }
/** /**
* @param array $handler * @param mixed $class
* @param mixed|null $method
* @return Router * @return Router
* @throws Exception * @throws Exception
*/ */
+11 -48
View File
@@ -6,20 +6,10 @@ namespace HttpServer\Abstracts;
use Database\Connection; use Database\Connection;
use Exception; use Exception;
use HttpServer\Http\Request;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use ReflectionException;
use Snowflake\Abstracts\Config; use Snowflake\Abstracts\Config;
use Snowflake\Core\Json;
use Snowflake\Error\LoggerProcess;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Exception\ComponentException;
use Snowflake\Exception\ConfigException; use Snowflake\Exception\ConfigException;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake; use Snowflake\Snowflake;
use Swoole\Process;
use Swoole\Server;
/** /**
@@ -30,7 +20,6 @@ abstract class Callback extends HttpService
{ {
const EVENT_ERROR = 'WORKER:ERROR'; const EVENT_ERROR = 'WORKER:ERROR';
const EVENT_STOP = 'WORKER:STOP'; const EVENT_STOP = 'WORKER:STOP';
const EVENT_EXIT = 'WORKER:EXIT'; const EVENT_EXIT = 'WORKER:EXIT';
@@ -42,43 +31,6 @@ abstract class Callback extends HttpService
self::EVENT_EXIT => 'The server exit. at No.', self::EVENT_EXIT => 'The server exit. at No.',
]; ];
/**
* @return PHPMailer
* @throws \PHPMailer\PHPMailer\Exception
* @throws ConfigException
*/
private function createEmail(): PHPMailer
{
$mail = new PHPMailer(true);
$mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = Config::get('email.host'); // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Debugoutput = false; // Enable SMTP authentication
$mail->CharSet = "UTF8"; // Enable SMTP authentication
$mail->Username = Config::get('email.username'); // SMTP username
$mail->Password = Config::get('email.password'); // SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
$mail->Port = Config::get('email.port'); // TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
$mail->setFrom(Config::get('email.send.address'), Config::get('email.send.nickname'));
return $mail;
}
/**
* @param $fd
* @param $data
* @param $reID
* @return Request
* @throws Exception
*/
protected function _request($fd, $data, $reID): Request
{
return Request::createListenRequest($fd, $data, $reID);
}
/** /**
* @param $messageContent * @param $messageContent
* @throws Exception * @throws Exception
@@ -132,6 +84,17 @@ abstract class Callback extends HttpService
} }
/**
* @param array $clientInfo
* @param string $event
* @return string
*/
protected function getName(array $clientInfo, string $event): string
{
return 'listen ' . $clientInfo['server_port'] . ' ' . Event::SERVER_CONNECT;
}
/** /**
* @throws ConfigException * @throws ConfigException
* @throws Exception * @throws Exception
+2 -15
View File
@@ -7,7 +7,6 @@ namespace HttpServer\Events;
use Exception; use Exception;
use HttpServer\Abstracts\Callback; use HttpServer\Abstracts\Callback;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Snowflake;
use Swoole\Server; use Swoole\Server;
/** /**
@@ -29,23 +28,11 @@ class OnClose extends Callback
try { try {
defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES)); defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES));
$clientInfo = $server->getClientInfo($fd); $clientInfo = $server->getClientInfo($fd);
if (!Event::exists(($name = $this->getName($clientInfo)))) {
return; Event::trigger($this->getName($clientInfo, Event::SERVER_CLIENT_CLOSE), [$server, $fd]);
}
Event::trigger($name, [$server, $fd]);
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
$this->addError($exception, 'throwable'); $this->addError($exception, 'throwable');
} }
} }
/**
* @param $server_port
* @return string
*/
private function getName($server_port): string
{
return 'listen ' . $server_port['server_port'] . ' ' . Event::SERVER_CLIENT_CLOSE;
}
} }
+1 -11
View File
@@ -33,21 +33,11 @@ class OnConnect extends Callback
if (isset($clientInfo['websocket_status'])) { if (isset($clientInfo['websocket_status'])) {
return; return;
} }
fire($this->getName($clientInfo), [$server, $fd, $reactorId]); fire($this->getName($clientInfo, Event::SERVER_CONNECT), [$server, $fd, $reactorId]);
} catch (\Throwable $throwable) { } catch (\Throwable $throwable) {
$this->addError($throwable, 'connect'); $this->addError($throwable, 'connect');
} }
} }
/**
* @param array $clientInfo
* @return string
*/
private function getName(array $clientInfo): string
{
return 'listen ' . $clientInfo['server_port'] . ' ' . Event::SERVER_CONNECT;
}
} }
+18 -41
View File
@@ -11,6 +11,7 @@ use HttpServer\Http\HttpHeaders;
use HttpServer\Http\HttpParams; use HttpServer\Http\HttpParams;
use HttpServer\Http\Request; use HttpServer\Http\Request;
use HttpServer\Http\Response; use HttpServer\Http\Response;
use HttpServer\Route\Router;
use ReflectionException; use ReflectionException;
use Snowflake\Core\ArrayAccess; use Snowflake\Core\ArrayAccess;
use Snowflake\Event; use Snowflake\Event;
@@ -32,9 +33,10 @@ class OnHandshake extends Callback
/** /**
* @param $request * @param $request
* @param $response * @param $response
* @return Router
* @throws Exception * @throws Exception
*/ */
private function resolveParse($request, $response) private function _protocol($request, $response): Router
{ {
/** @var Server $server */ /** @var Server $server */
$secWebSocketKey = $request->header['sec-websocket-key']; $secWebSocketKey = $request->header['sec-websocket-key'];
@@ -55,36 +57,23 @@ class OnHandshake extends Callback
foreach ($headers as $key => $val) { foreach ($headers as $key => $val) {
$response->header($key, $val); $response->header($key, $val);
} }
return Snowflake::app()->getRouter();
} }
/** /**
* @param SResponse $response * @param SResponse $response
* @param int $code * @param int $code
* @return false * @return void
*/ */
private function disconnect(SResponse $response, $code = 500): bool private function disconnect(SResponse $response, int $code = 500): void
{ {
$server = Snowflake::getWebSocket(); $server = Snowflake::getWebSocket();
if (!$server->exist($response->fd)) { if (!$server->isEstablished($response->fd)) {
return false; return;
} }
$response->status($code); $response->status($code);
$response->end(); $response->end();
return false;
}
/**
* @param $response
* @param int $code
* @return false
*/
private function connect($response, $code = 101): bool
{
$response->status($code);
$response->end();
return false;
} }
@@ -99,7 +88,15 @@ class OnHandshake extends Callback
try { try {
defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES)); defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES));
$this->execute($request, $response); $router = $this->_protocol($request, $response);
[$sRequest, $sResponse] = $this->sRequest($request, $response);
if (($node = $router->find_path($sRequest)) !== null) {
$node->dispatch($sRequest, $sResponse);
} else {
$this->disconnect($response, 404);
}
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
$this->addError($exception, 'throwable'); $this->addError($exception, 'throwable');
$response->status(500); $response->status(500);
@@ -108,33 +105,13 @@ class OnHandshake extends Callback
} }
/**
* @param SRequest $request
* @param SResponse $response
* @return mixed
* @throws Exception
*/
private function execute(SRequest $request, SResponse $response): mixed
{
$this->resolveParse($request, $response);
$router = Snowflake::app()->getRouter();
[$sRequest, $sResponse] = $this->sRequest($request, $response);
if (($node = $router->find_path($sRequest)) !== null) {
return $node->dispatch($sRequest, $sResponse);
}
return $this->disconnect($response, 404);
}
/** /**
* @param $request * @param $request
* @param SResponse $response * @param SResponse $response
* @return array * @return array
* @throws NotFindClassException * @throws NotFindClassException
* @throws ReflectionException * @throws ReflectionException
* @throws Exception
*/ */
private function sRequest($request, SResponse $response): array private function sRequest($request, SResponse $response): array
{ {
+1 -1
View File
@@ -18,7 +18,7 @@ class OnManagerStop extends Callback
{ {
/** /**
* @param $server * @param Server $server
* @throws Exception * @throws Exception
*/ */
public function onHandler(Server $server) public function onHandler(Server $server)
+4 -27
View File
@@ -4,22 +4,8 @@ declare(strict_types=1);
namespace HttpServer\Events; namespace HttpServer\Events;
use Annotation\Route\Socket;
use Exception;
use HttpServer\Abstracts\Callback; use HttpServer\Abstracts\Callback;
use HttpServer\Http\Context;
use HttpServer\Http\HttpHeaders;
use HttpServer\Http\HttpParams;
use HttpServer\Http\Request;
use ReflectionException;
use Snowflake\Abstracts\Config;
use Snowflake\Core\Json;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Exception\ComponentException;
use Snowflake\Exception\ConfigException;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake;
use Swoole\Coroutine;
use Swoole\WebSocket\Frame; use Swoole\WebSocket\Frame;
use Swoole\WebSocket\Server; use Swoole\WebSocket\Server;
@@ -42,7 +28,10 @@ class OnMessage extends Callback
if ($frame->opcode === 0x08) { if ($frame->opcode === 0x08) {
return; return;
} }
Event::trigger($this->getName($server, $frame), [$frame, $server]);
$clientInfo = $this->getName($server->getClientInfo($frame->fd), Event::SERVER_MESSAGE);
Event::trigger($clientInfo, [$frame, $server]);
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
$this->addError($exception, 'websocket'); $this->addError($exception, 'websocket');
if (!swoole()->isEstablished($frame->fd)) { if (!swoole()->isEstablished($frame->fd)) {
@@ -52,16 +41,4 @@ class OnMessage extends Callback
} }
} }
/**
* @param $clientInfo
* @return string
*/
private function getName(Server $server, Frame $frame): string
{
$clientInfo = $server->getClientInfo($frame->fd);
return 'listen ' . $clientInfo['server_port'] . ' ' . Event::SERVER_MESSAGE;
}
} }
+13 -29
View File
@@ -8,7 +8,6 @@ use Exception;
use HttpServer\Abstracts\Callback; use HttpServer\Abstracts\Callback;
use Snowflake\Core\Json; use Snowflake\Core\Json;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Snowflake;
use Swoole\Server; use Swoole\Server;
/** /**
@@ -18,45 +17,30 @@ use Swoole\Server;
class OnPacket extends Callback class OnPacket extends Callback
{ {
public int $port = 0;
public string $host = '';
/** /**
* @param Server $server * @param Server $server
* @param $data * @param string $data
* @param $clientInfo * @param array $client
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
public function onHandler(Server $server, string $data, array $clientInfo): mixed public function onHandler(Server $server, string $data, array $client): mixed
{ {
[$host, $port] = [$clientInfo['address'], $clientInfo['port']];
try { try {
defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES)); defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES));
$request = $this->_request($clientInfo, $server, $data); $client['server_port'] = $client['port'];
$name = $this->getName($client, Event::SERVER_RECEIVE);
$router = Snowflake::app()->getRouter(); $result = Event::trigger($name, [$server, $data, $client]);
if (($node = $router->find_path($request)) === null) {
return $server->sendto($host, $port, Json::encode(['state' => 404]));
}
$dispatch = $node->dispatch();
if (!is_string($dispatch)) $dispatch = Json::encode($dispatch);
if (empty($dispatch)) {
$dispatch = Json::encode(['state' => 0, 'message' => 'ok']);
}
return $server->sendto($host, $port, $dispatch);
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
$this->addError($exception, 'packet'); $result = logger()->exception($exception);
} finally {
$response = Json::encode(['state' => 500, 'message' => $exception->getMessage()]); if (is_array($result) || is_object($result)) {
$result = Json::encode($result);
return $server->sendto($host, $port, $response); }
$sendData = [$client['address'], $client['port'], $result];
return $server->sendto(...$sendData);
} }
} }
+13 -36
View File
@@ -7,12 +7,9 @@ namespace HttpServer\Events;
use Exception; use Exception;
use HttpServer\Abstracts\Callback; use HttpServer\Abstracts\Callback;
use HttpServer\Http\Request; use HttpServer\Http\Request;
use HttpServer\Route\Router; use Snowflake\Abstracts\Config;
use ReflectionException;
use Snowflake\Core\Json; use Snowflake\Core\Json;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Exception\NotFindClassException;
use Snowflake\Snowflake;
use Swoole\Server; use Swoole\Server;
/** /**
@@ -22,21 +19,6 @@ use Swoole\Server;
class OnReceive extends Callback class OnReceive extends Callback
{ {
public int $port = 0;
public string $host = '';
private Router $router;
public function init()
{
$this->router = Snowflake::app()->getRouter();
}
/** /**
* @param Server $server * @param Server $server
* @param int $fd * @param int $fd
@@ -50,26 +32,21 @@ class OnReceive extends Callback
try { try {
defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES)); defer(fn() => fire(Event::SYSTEM_RESOURCE_RELEASES));
$request = $this->_request($fd, $data, $reID); $client = $server->getClientInfo($fd, $reID);
if (($node = $this->router->find_path($request)) === null) { $name = $this->getName($client, Event::SERVER_RECEIVE);
return $server->send($fd, Json::encode(['state' => 404]));
if (Config::get('rpc.port', 0) == $client['server_port']) {
$result = router()->find_path(Request::rpcRequest($fd, $data, $reID))?->dispatch();
} else {
$result = Event::trigger($name, [$server, $data, $client]);
} }
$dispatch = $node->dispatch(); if (is_array($result) || is_object($result)) {
if (!is_string($dispatch)) $dispatch = Json::encode($dispatch); $result = Json::encode($result);
if (empty($dispatch)) {
$dispatch = Json::encode(['state' => 0, 'message' => 'ok']);
} }
if ($server->exist($fd)) {
return $server->send($fd, $dispatch);
}
return $dispatch;
} catch (\Throwable $exception) { } catch (\Throwable $exception) {
$this->addError($exception, 'receive'); $result = logger()->exception($exception);
$error = ['state' => 500, 'message' => $exception->getMessage()]; } finally {
if ($server->exist($fd)) { return $server->send($fd, $result);
return $server->send($fd, Json::encode($error));
}
return Json::encode($error);
} }
} }
-2
View File
@@ -6,9 +6,7 @@ namespace HttpServer\Events;
use Exception; use Exception;
use HttpServer\Abstracts\Callback; use HttpServer\Abstracts\Callback;
use Snowflake\Error\Logger;
use Snowflake\Event; use Snowflake\Event;
use Snowflake\Snowflake;
use Swoole\Timer; use Swoole\Timer;
/** /**
+13 -28
View File
@@ -415,10 +415,10 @@ class Request extends HttpService
{ {
$mainstay = sprintf("%.6f", microtime(true)); // 带毫秒的时间戳 $mainstay = sprintf("%.6f", microtime(true)); // 带毫秒的时间戳
$timestamp = floor($mainstay); // 时间戳 $timestamp = floatval($mainstay); // 时间戳
$milliseconds = round(($mainstay - $timestamp) * 1000); // 毫秒 $milliseconds = round(($mainstay - $timestamp) * 1000); // 毫秒
$datetime = date("Y-m-d H:i:s", $timestamp) . '.' . $milliseconds; $datetime = date("Y-m-d H:i:s", (int)$timestamp) . '.' . $milliseconds;
$tmp = [ $tmp = [
'[Debug ' . $datetime . '] ', '[Debug ' . $datetime . '] ',
@@ -427,7 +427,6 @@ class Request extends HttpService
'`' . $this->headers->getHeader('user-agent') . '`', '`' . $this->headers->getHeader('user-agent') . '`',
$this->getRuntime() $this->getRuntime()
]; ];
return implode(' ', $tmp); return implode(' ', $tmp);
} }
@@ -500,10 +499,11 @@ class Request extends HttpService
* @param $fd * @param $fd
* @param $data * @param $data
* @param int $reID * @param int $reID
* @return Request * @return mixed|null
* @throws ConfigException
* @throws Exception * @throws Exception
*/ */
public static function createListenRequest($fd, $data, $reID = 0): Request public static function rpcRequest($fd, $data, int $reID = 0): Request|null
{ {
$sRequest = new Request(); $sRequest = new Request();
@@ -514,28 +514,11 @@ class Request extends HttpService
$sRequest->params = new HttpParams($data, [], []); $sRequest->params = new HttpParams($data, [], []);
$port = $sRequest->clientInfo['server_port']; $port = $sRequest->clientInfo['server_port'];
$sRequest->headers->setRequestUri('add-port-listen/port_' . $port);
$sRequest->headers->setRequestMethod(self::HTTP_LISTEN);
$sRequest->checkIsRpcClient()->parseUri();
return Context::setContext('request', $sRequest);
}
/**
* @throws ConfigException
* @throws Exception
*/
private function checkIsRpcClient(): static
{
$port = $this->clientInfo['server_port'];
if (($rpc = Config::get('rpc.port', 0)) !== $port) { if (($rpc = Config::get('rpc.port', 0)) !== $port) {
return $this; return null;
} }
[$cmd, $repeat, $body] = explode("\n", $this->params->getBody()); [$cmd, $repeat, $body] = explode("\n", $sRequest->params->getBody());
if (is_null($body) || is_null($cmd) || !empty($repeat)) { if (is_null($body) || is_null($cmd) || !empty($repeat)) {
throw new Exception('Protocol format error.'); throw new Exception('Protocol format error.');
} }
@@ -543,10 +526,12 @@ class Request extends HttpService
if (is_string($body) && is_null($data = Json::decode($body))) { if (is_string($body) && is_null($data = Json::decode($body))) {
throw new Exception('Protocol format error.'); throw new Exception('Protocol format error.');
} }
$this->headers->setRequestUri('rpc/p' . $rpc . '/' . ltrim($cmd, '/'));
$this->headers->setRequestMethod(Request::HTTP_CMD);
return $this; $sRequest->params->setPosts($data);
$sRequest->headers->setRequestUri('rpc/p' . $rpc . '/' . ltrim($cmd, '/'));
$sRequest->headers->setRequestMethod(Request::HTTP_CMD);
return Context::setContext('request', $sRequest);
} }
@@ -556,7 +541,7 @@ class Request extends HttpService
* @return mixed * @return mixed
* @throws Exception * @throws Exception
*/ */
private static function getClientInfo($fd, $re = 0): mixed private static function getClientInfo($fd, int $re = 0): mixed
{ {
$server = Snowflake::app()->getSwoole(); $server = Snowflake::app()->getSwoole();
if (!is_array($fd)) { if (!is_array($fd)) {