Skip to content

由前一节可知,事件的注册在Hyerf\Server\Server类的registerSwooleEvents方法中完成。 注册的回调事件的执行顺序如下:

所属类事件描述触发时机触发顺序
StartCallbackonStart当 swoole_server 实例启动后触发仅当 master 进程启动成功后触发1
ManagerStartCallbackonManagerStart当 swoole_server 实例启动后触发仅当 manager 进程启动成功后触发2
WorkerStartCallbackonWorkerStart当 worker 进程启动后触发仅当 worker 进程启动成功后触发3
WorkerStopCallbackonWorkerStop当 worker 进程关闭后触发仅当 worker 进程关闭后触发4
WorkerExitCallbackonWorkerExit当 worker 进程退出后触发仅当 worker 进程退出后触发5
ServeronRequest当接收到请求时触发仅当 worker 进程接收到请求后触发6
PipeMessageCallbackonPipeMessage当接收到消息时触发仅当 worker 进程接收到消息后触发7

要理解上面事件,请参考Swoole的运行流程。

Swoole流程

首先了解Swoole的运行流程,(图源网络) 具体内容参考swoole官网

当请求过来时,会触发onRequest事件,然后执行onRequest回调函数。

OnRequest方法

php
public function onRequest($request, $response): void
{
    try {
        CoordinatorManager::until(Constants::WORKER_START)->yield();

        [$psr7Request, $psr7Response] = $this->initRequestAndResponse($request, $response);
        $psr7Request = $this->coreMiddleware->dispatch($psr7Request);
        $this->option?->isEnableRequestLifecycle() && $this->event?->dispatch(new RequestReceived(
            request: $psr7Request,
            response: $psr7Response,
            server: $this->serverName
        ));

        /** @var Dispatched $dispatched */
        $dispatched = $psr7Request->getAttribute(Dispatched::class);
        $middlewares = $this->middlewares;
        $registeredMiddlewares = [];
        if ($dispatched->isFound()) {
            $registeredMiddlewares = MiddlewareManager::get($this->serverName, $dispatched->handler->route, $psr7Request->getMethod());
            $middlewares = array_merge($middlewares, $registeredMiddlewares);
        }

        if ($this->option?->isMustSortMiddlewares() || $registeredMiddlewares) {
            $middlewares = MiddlewareManager::sortMiddlewares($middlewares);
        }

        $psr7Response = $this->dispatcher->dispatch($psr7Request, $middlewares, $this->coreMiddleware);
    } catch (Throwable $throwable) {
        // Delegate the exception to exception handler.
        $psr7Response = $this->container->get(SafeCaller::class)->call(function () use ($throwable) {
            return $this->exceptionHandlerDispatcher->dispatch($throwable, $this->exceptionHandlers);
        }, static function () {
            return (new Psr7Response())->withStatus(400);
        });
    } finally {
        // isEnableRequestLifecycle默认不开启
        if (isset($psr7Request) && $this->option?->isEnableRequestLifecycle()) {
            defer(fn () => $this->event?->dispatch(new RequestTerminated(
                request: $psr7Request,
                response: $psr7Response ?? null,
                exception: $throwable ?? null,
                server: $this->serverName
            )));

            $this->event?->dispatch(new RequestHandled(
                request: $psr7Request,
                response: $psr7Response ?? null,
                exception: $throwable ?? null,
                server: $this->serverName
            ));
        }

        // Send the Response to client.
        if (! isset($psr7Response) || ! $psr7Response instanceof ResponseInterface) {
            return;
        }
        // 发送响应到客户端
        if (isset($psr7Request) && $psr7Request->getMethod() === 'HEAD') {
            $this->responseEmitter->emit($psr7Response, $response, false);
        } else {
            $this->responseEmitter->emit($psr7Response, $response);
        }
    }
}

CoordinatorManager类

CoordinatorManager::until用于创建一个协程等待器,指示协程等待某个事件的完成, 这里是等待worker进程启动完成。

php
CoordinatorManager::until(Constants::WORKER_START)->yield();

确保在处理请求之前,所有的Worker进程都已经启动完成,以保证后续的操作能够顺利执行。

initRequestAndResponse方法

将请求和响应对象转换为符合 PSR-7标准的对象。

php
[$psr7Request, $psr7Response] = $this->initRequestAndResponse($request, $response);