Skip to content

Commit

Permalink
feat: complete the tcp request middleware logic. add some unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Oct 23, 2019
1 parent 40c278a commit 6b59387
Show file tree
Hide file tree
Showing 29 changed files with 187 additions and 117 deletions.
5 changes: 4 additions & 1 deletion src/server/src/Concern/CommonProtocolDataTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,13 @@ public function getExt(): array

/**
* @param array $ext
*
* @return $this
*/
public function setExt(array $ext): void
public function setExt(array $ext): self
{
$this->ext = $ext;
return $this;
}

/**
Expand Down
22 changes: 11 additions & 11 deletions src/tcp-server/phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
bootstrap="test/bootstrap.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
bootstrap="test/bootstrap.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="test">
<directory suffix="Test.php">./test/unit</directory>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ final class TcpControllerParser extends Parser
/**
* Parse object
*
* @param int $type Class or Method or Property
* @param int $type Class or Method or Property
* @param TcpController $annotation Annotation object
*
* @return array
Expand Down
4 changes: 2 additions & 2 deletions src/tcp-server/src/Context/TcpConnectContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class TcpConnectContext extends AbstractContext
protected $reactorId;

/**
* @param int $fd
* @param int $reactorId
* @param int $fd
* @param int $reactorId
*
* @return self
*/
Expand Down
2 changes: 1 addition & 1 deletion src/tcp-server/src/Context/TcpReceiveContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function clear(): void
{
parent::clear();

$this->request = null;
$this->request = null;
$this->response = null;
}

Expand Down
4 changes: 2 additions & 2 deletions src/tcp-server/src/Contract/MiddlewareInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
interface MiddlewareInterface
{
/**
* @param RequestInterface|Request $request
* @param RequestHandlerInterface $handler
* @param RequestInterface|Request $request
* @param RequestHandlerInterface $handler
*
* @return ResponseInterface|Response
*/
Expand Down
4 changes: 1 addition & 3 deletions src/tcp-server/src/MiddlewareChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,7 @@ public function handle(RequestInterface $request): ResponseInterface
}

if (!$response instanceof ResponseInterface) {
throw new TcpMiddlewareException(
'Middleware must return object and instance of ' . ResponseInterface::class
);
throw new TcpMiddlewareException('Middleware must return object and instance of ' . ResponseInterface::class);
}

return $response;
Expand Down
9 changes: 8 additions & 1 deletion src/tcp-server/src/Request.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,16 @@ class Request implements RequestInterface

/**
* The request data key for storage matched route info.
* eg:
* [
* status,
* [
* command => string,
* handler => [class, method],
* ]
* ]
*/
public const ROUTE_INFO = '__route';
public const COMMAND = '__cmd';

/**
* Receiver fd
Expand Down
16 changes: 6 additions & 10 deletions src/tcp-server/src/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Log\Helper\CLog;
use Swoft\Tcp\Protocol;
use Swoft\Tcp\Response as TcpResponse;
use Swoft\Tcp\Server\Contract\ResponseInterface;
use Swoft\Tcp\Server\Exception\TcpResponseException;
use Swoft\Tcp\Response as TcpResponse;
use Swoole\Server;

/**
Expand Down Expand Up @@ -72,17 +72,13 @@ public function send(Server $server = null): int
return 0;
}

// Fix: No response data
if ($this->isEmpty()) {
return 0;
}

/** @var Protocol $protocol */
$protocol = Swoft::getBean('tcpServerProtocol');
$protocol = Swoft::getBean('tcpServerProtocol');
$this->sent = true;

// Content is empty, skip send
if (!$content = $protocol->packResponse($this)) {
$this->sent = true;
$content = $protocol->packResponse($this);
if ('' === $content) {
CLog::warning('cannot send empty content to tcp client');
return 0;
}
Expand All @@ -92,12 +88,12 @@ public function send(Server $server = null): int
// Trigger event before push message content to client
Swoft::trigger(TcpServerEvent::CONTENT_SEND, $server, $content, $this);

// Do send content
if ($server->send($this->fd, $content) === false) {
$code = $server->getLastError();
throw new TcpResponseException("Error on send data to client #{$this->fd}", $code);
}

$this->sent = true;
return 1;
}

Expand Down
1 change: 1 addition & 0 deletions src/tcp-server/src/Router/RouteRegister.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ final class RouteRegister
* middles => [middleware0],
* ]
* ]
*
* @var array
*/
private static $controllers = [];
Expand Down
4 changes: 3 additions & 1 deletion src/tcp-server/src/Router/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class Router implements RouterInterface
* 'handler' => [class, method],
* ]
* ]
*
* @var array
*/
private $routes = [];
Expand All @@ -30,6 +31,7 @@ class Router implements RouterInterface
* [
* 'command name' => [middle1, middle2],
* ]
*
* @var array
*/
private $middlewares = [];
Expand Down Expand Up @@ -112,7 +114,7 @@ public function addMiddlewares(string $cmd, array $middlewares): void
*
* @return array
*/
public function getMiddlewaresByCmd(string $cmd): array
public function getCmdMiddlewares(string $cmd): array
{
return $this->middlewares[$cmd] ?? [];
}
Expand Down
3 changes: 1 addition & 2 deletions src/tcp-server/src/Swoole/ReceiveListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ public function onReceive(Server $server, int $fd, int $reactorId, string $data)

/** @var TcpErrorDispatcher $errDispatcher */
$errDispatcher = Swoft::getSingleton(TcpErrorDispatcher::class);
$errDispatcher->receiveError($e, $response);

// Dispatching error handle
$response = $errDispatcher->receiveError($e, $response);
$response->send($server);
} finally {
// Defer
Expand Down
44 changes: 30 additions & 14 deletions src/tcp-server/src/TcpDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class TcpDispatcher implements MiddlewareInterface

/**
* Pre-check whether the route matches successfully.
* True - Check if the status matches successfully after matching.
* False - check the status after the middleware process
*
* @var bool
*/
Expand All @@ -51,21 +53,21 @@ class TcpDispatcher implements MiddlewareInterface
*
* @var array
*/
protected $middlewares = [];
private $middlewares = [];

/**
* User defined global pre-middlewares
*
* @var array
*/
protected $preMiddlewares = [];
private $preMiddlewares = [];

/**
* User defined global after-middlewares
*
* @var array
*/
protected $afterMiddlewares = [];
private $afterMiddlewares = [];

/**
* @param Request $request
Expand Down Expand Up @@ -100,15 +102,17 @@ public function dispatch(Request $request, Response $response): ResponseInterfac
$status = $result[0];

// Storage route info
$request->set(Request::COMMAND, $command);
$request->set(Request::ROUTE_INFO, $result);

// Found, get command middlewares
$middlewares = [];
if ($status === Router::FOUND) {
$cmdMiddles = $router->getMiddlewaresByCmd($command);
$middlewares = $router->getCmdMiddlewares($command);

// append middlewares
$this->addMiddlewares($cmdMiddles);
// Append command middlewares
if ($middlewares) {
$middlewares = array_merge($this->middlewares, $middlewares);
}

// If this->preCheckRoute is True, pre-check route match status
} elseif ($this->preCheckRoute) {
Expand All @@ -117,10 +121,12 @@ public function dispatch(Request $request, Response $response): ResponseInterfac
}

// Has middlewares
if ($middlewares = $this->mergeMiddlewares()) {
if ($middlewares = $this->mergeMiddlewares($middlewares)) {
$chain = MiddlewareChain::new($this);
$chain->addMiddles($middlewares);

server()->log('request will use middleware process, middleware count: ' . $chain->count(), [], 'debug');

return $chain->run($request);
}

Expand Down Expand Up @@ -238,11 +244,11 @@ public function getMiddlewares(): array
}

/**
* @param array $middlewares
* @param string $middleware
*/
public function setMiddlewares(array $middlewares): void
public function addMiddleware(string $middleware): void
{
$this->middlewares = $middlewares;
$this->middlewares[] = $middleware;
}

/**
Expand All @@ -255,6 +261,14 @@ public function addMiddlewares(array $middlewares): void
}
}

/**
* @param array $middlewares
*/
public function setMiddlewares(array $middlewares): void
{
$this->middlewares = $middlewares;
}

/**
* @return array
*/
Expand Down Expand Up @@ -290,12 +304,14 @@ public function setAfterMiddlewares(array $afterMiddlewares): void
/**
* merge all middlewares
*
* @param array $middlewares
*
* @return array
*/
protected function mergeMiddlewares(): array
protected function mergeMiddlewares(array $middlewares): array
{
if ($this->middlewares) {
return array_merge($this->preMiddlewares, $this->middlewares, $this->afterMiddlewares);
if ($middlewares) {
return array_merge($this->preMiddlewares, $middlewares, $this->afterMiddlewares);
}

return array_merge($this->preMiddlewares, $this->afterMiddlewares);
Expand Down
Loading

0 comments on commit 6b59387

Please sign in to comment.