container->has(EventDispatcherInterface::class)) { $this->event = $this->container->get(EventDispatcherInterface::class); } } public function initCoreMiddleware(string $serverName): void { $this->serverName = $serverName; $this->coreMiddleware = $this->createCoreMiddleware(); $config = $this->container->get(ConfigInterface::class); $this->middlewares = $config->get('middlewares.' . $serverName, []); $this->exceptionHandlers = $config->get('exceptions.handler.' . $serverName, $this->getDefaultExceptionHandler()); $this->initOption(); } public function onReceive($server, int $fd, int $reactorId, string $data): void { $request = $response = null; try { CoordinatorManager::until(Constants::WORKER_START)->yield(); // Initialize PSR-7 Request and Response objects. RequestContext::set($request = $this->buildRequest($fd, $reactorId, $data)); ResponseContext::set($response = $this->buildResponse($fd, $server)); $request = $this->coreMiddleware->dispatch($request); $middlewares = $this->middlewares; $this->option?->isEnableRequestLifecycle() && $this->event?->dispatch(new RequestReceived( request: $request, response: $response, serverName: $this->serverName )); $response = $this->dispatcher->dispatch($request, $middlewares, $this->coreMiddleware); } catch (Throwable $throwable) { // Delegate the exception to exception handler. $exceptionHandlerDispatcher = $this->container->get(ExceptionHandlerDispatcher::class); $response = $exceptionHandlerDispatcher->dispatch($throwable, $this->exceptionHandlers); } finally { if (isset($request) && $this->option?->isEnableRequestLifecycle()) { defer(fn () => $this->event?->dispatch(new RequestTerminated( request: $request, response: $response ?? null, exception: $throwable ?? null, serverName: $this->serverName ))); $this->event?->dispatch(new RequestHandled( request: $request, response: $response ?? null, exception: $throwable ?? null, serverName: $this->serverName )); } if (! $response instanceof ResponseInterface) { $response = $this->transferToResponse($response); } if ($response) { $this->send($server, $fd, $response); } } } public function onConnect($server, int $fd) { // $server is the main server object, not the server object that this callback on. /* @var \Swoole\Server\Port */ [$type, $port] = ServerManager::get($this->serverName); $this->logger->debug(sprintf('Connect to %s:%d', $port->host, $port->port)); } public function onClose($server, int $fd) { // $server is the main server object, not the server object that this callback on. /* @var \Swoole\Server\Port */ [$type, $port] = ServerManager::get($this->serverName); $this->logger->debug(sprintf('Close on %s:%d', $port->host, $port->port)); } protected function getDefaultExceptionHandler(): array { return [ HttpExceptionHandler::class, ]; } /** * @param Connection|SwooleServer $server */ protected function send($server, int $fd, ResponseInterface $response): void { if ($server instanceof SwooleServer) { $server->send($fd, (string) $response->getBody()); } elseif ($server instanceof Connection) { $server->send((string) $response->getBody()); } } abstract protected function createCoreMiddleware(): CoreMiddlewareInterface; abstract protected function buildRequest(int $fd, int $reactorId, string $data): ServerRequestPlusInterface; abstract protected function buildResponse(int $fd, $server): ResponsePlusInterface; protected function transferToResponse($response): ?ResponseInterface { return ResponseContext::getOrNull()?->setBody(new SwooleStream($response)); } protected function getContext() { return $this->container->get(RpcContext::class); } protected function initOption(): void { $ports = $this->container->get(ServerFactory::class)->getConfig()?->getServers(); if (! $ports) { return; } foreach ($ports as $port) { if ($port->getName() === $this->serverName) { $this->option = $port->getOptions(); } } $this->option ??= Option::make([]); $this->option->setMustSortMiddlewaresByMiddlewares($this->middlewares); } }