.gitattributes000064400000000105151360554500007437 0ustar00/.github export-ignore /examples export-ignore /tests export-ignore .gitignore000064400000000044151360554500006536 0ustar00/vendor/ composer.lock *.cache *.log.php-cs-fixer.php000064400000004755151360554500007657 0ustar00setRiskyAllowed(true) ->setRules([ '@PSR2' => true, '@Symfony' => true, '@DoctrineAnnotation' => true, '@PhpCsFixer' => true, 'header_comment' => [ 'comment_type' => 'PHPDoc', 'header' => $header, 'separate' => 'none', 'location' => 'after_declare_strict', ], 'array_syntax' => [ 'syntax' => 'short' ], 'list_syntax' => [ 'syntax' => 'short' ], 'concat_space' => [ 'spacing' => 'one' ], 'blank_line_before_statement' => [ 'statements' => [ 'declare', ], ], 'general_phpdoc_annotation_remove' => [ 'annotations' => [ 'author' ], ], 'ordered_imports' => [ 'imports_order' => [ 'class', 'function', 'const', ], 'sort_algorithm' => 'alpha', ], 'single_line_comment_style' => [ 'comment_types' => [ ], ], 'yoda_style' => [ 'always_move_variable' => false, 'equal' => false, 'identical' => false, ], 'phpdoc_align' => [ 'align' => 'left', ], 'multiline_whitespace_before_semicolons' => [ 'strategy' => 'no_multi_line', ], 'constant_case' => [ 'case' => 'lower', ], 'class_attributes_separation' => true, 'combine_consecutive_unsets' => true, 'declare_strict_types' => true, 'linebreak_after_opening_tag' => true, 'lowercase_static_reference' => true, 'no_useless_else' => true, 'no_unused_imports' => true, 'not_operator_with_successor_space' => true, 'not_operator_with_space' => false, 'ordered_class_elements' => true, 'php_unit_strict' => false, 'phpdoc_separation' => false, 'single_quote' => true, 'standardize_not_equals' => true, 'multiline_comment_opening_closing' => true, ]) ->setFinder( PhpCsFixer\Finder::create() ->exclude('vendor') ->in(__DIR__) ) ->setUsingCache(false); .phpstorm.meta.php000064400000000164151360554500010141 0ustar00" version="1.0" license="MIT" app.name="Hyperf" ARG timezone ARG PHP_VERSION ENV TIMEZONE=${timezone:-"Asia/Shanghai"} ENV COMPOSER_ROOT_VERSION="v2.0.0" # update RUN set -ex \ # show php version and extensions && php -v \ && php -m \ && php --ri swoole \ # ---------- some config ---------- && cd /etc/php* \ # - config PHP && { \ echo "upload_max_filesize=128M"; \ echo "post_max_size=128M"; \ echo "memory_limit=1G"; \ echo "date.timezone=${TIMEZONE}"; \ } | tee conf.d/99_overrides.ini \ # - config timezone && ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \ && echo "${TIMEZONE}" > /etc/timezone \ # ---------- clear works ---------- && rm -rf /var/cache/apk/* /tmp/* /usr/share/man \ && echo -e "\033[42;37m Build Completed :).\033[0m\n" WORKDIR /opt/www COPY . /opt/www README.md000064400000000234151360554500006026 0ustar00# Swoole Engine ![Swoole Engine Test](https://github.com/hyperf/engine/workflows/Swoole%20Engine%20Test/badge.svg) ``` composer require hyperf/engine ``` composer.json000064400000002400151360554500007266 0ustar00{ "name": "hyperf/engine", "type": "library", "license": "MIT", "keywords": [ "php", "hyperf" ], "description": "", "autoload": { "psr-4": { "Hyperf\\Engine\\": "src/" } }, "autoload-dev": { "psr-4": { "HyperfTest\\": "tests" } }, "require": { "php": ">=8.0", "hyperf/engine-contract": "^1.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", "hyperf/guzzle": "^3.0", "phpstan/phpstan": "^1.0", "phpunit/phpunit": "^9.4", "swoole/ide-helper": "dev-master" }, "suggest": { "ext-swoole": ">=5.0" }, "conflict": { "ext-swoole": "<5.0" }, "minimum-stability": "dev", "prefer-stable": true, "config": { "optimize-autoloader": true, "sort-packages": true }, "extra": { "branch-alias": { "dev-master": "2.0-dev" }, "hyperf": { "config": "Hyperf\\Engine\\ConfigProvider" } }, "scripts": { "test": "phpunit -c phpunit.xml --colors=always", "analyse": "phpstan analyse --memory-limit 1024M -l 0 ./src", "cs-fix": "php-cs-fixer fix $1" } } phpunit.xml000064400000000755151360554500006770 0ustar00 ./tests/ src/Channel.php000064400000003321151360554500007417 0ustar00capacity; } public function getLength(): int { return $this->length(); } public function isAvailable(): bool { return ! $this->isClosing(); } public function close(): bool { $this->closed = true; return parent::close(); } public function hasProducers(): bool { throw new RuntimeException('Not supported.'); } public function hasConsumers(): bool { throw new RuntimeException('Not supported.'); } public function isReadable(): bool { throw new RuntimeException('Not supported.'); } public function isWritable(): bool { throw new RuntimeException('Not supported.'); } public function isClosing(): bool { return $this->closed || $this->errCode === SWOOLE_CHANNEL_CLOSED; } public function isTimeout(): bool { return ! $this->closed && $this->errCode === SWOOLE_CHANNEL_TIMEOUT; } } src/ConfigProvider.php000064400000001110151360554500010761 0ustar00 [ SocketFactoryInterface::class => SocketFactory::class, ], ]; } } src/Constant.php000064400000001041151360554500007635 0ustar00callable = $callable; } public static function create(callable $callable, ...$data): static { $coroutine = new static($callable); $coroutine->execute(...$data); return $coroutine; } public function execute(...$data): static { $this->id = SwooleCo::create($this->callable, ...$data); return $this; } public function getId(): int { if (is_null($this->id)) { throw new RuntimeException('Coroutine was not be executed.'); } return $this->id; } public static function id(): int { return SwooleCo::getCid(); } public static function pid(?int $id = null): int { if ($id) { $cid = SwooleCo::getPcid($id); if ($cid === false) { throw new CoroutineDestroyedException(sprintf('Coroutine #%d has been destroyed.', $id)); } } else { $cid = SwooleCo::getPcid(); } if ($cid === false) { throw new RunningInNonCoroutineException('Non-Coroutine environment don\'t has parent coroutine id.'); } return max(0, $cid); } public static function set(array $config): void { SwooleCo::set($config); } public static function getContextFor(?int $id = null): ?ArrayObject { if ($id === null) { return SwooleCo::getContext(); } return SwooleCo::getContext($id); } public static function defer(callable $callable): void { SwooleCo::defer($callable); } /** * Yield the current coroutine. * @param mixed $data only Support Swow * @return bool */ public static function yield(mixed $data = null): mixed { return SwooleCo::yield(); } /** * Resume the coroutine by coroutine Id. * @param mixed $data only Support Swow * @return bool */ public static function resumeById(int $id, mixed ...$data): mixed { return SwooleCo::resume($id); } } src/Exception/CoroutineDestroyedException.php000064400000000521151360554500015515 0ustar00setMethod($method); $this->setData($contents); $this->setHeaders($this->encodeHeaders($headers)); $this->execute($path); if ($this->errCode !== 0) { throw new HttpClientException($this->errMsg, $this->errCode); } return new RawResponse( $this->statusCode, $this->decodeHeaders($this->headers ?? []), $this->body, $version ); } /** * @param string[] $headers * @return string[][] */ private function decodeHeaders(array $headers): array { $result = []; foreach ($headers as $name => $header) { // The key of header is lower case. $result[$name][] = $header; } if ($this->set_cookie_headers) { $result['set-cookie'] = $this->set_cookie_headers; } return $result; } /** * Swoole engine not support two-dimensional array. * @param string[][] $headers * @return string[] */ private function encodeHeaders(array $headers): array { $result = []; foreach ($headers as $name => $value) { $result[$name] = is_array($value) ? implode(',', $value) : $value; } return $result; } } src/Http/FdGetter.php000064400000000626151360554500010477 0ustar00fd; } } src/Http/RawResponse.php000064400000001612151360554500011237 0ustar00statusCode; } public function getHeaders(): array { return $this->headers; } public function getBody(): string { return $this->body; } public function getVersion(): string { return $this->version; } } src/Signal.php000064400000001006151360554500007262 0ustar00getProtocol()) { $socket->setProtocol($protocol); } if ($option->getTimeout() === null) { $res = $socket->connect($option->getHost(), $option->getPort()); } else { $res = $socket->connect($option->getHost(), $option->getPort(), $option->getTimeout()); } if (! $res) { throw new SocketConnectException($socket->errMsg, $socket->errCode); } return $socket; } } src/Socket/SocketOption.php000064400000001542151360554500011723 0ustar00host; } public function getPort(): int { return $this->port; } public function getTimeout(): ?float { return $this->timeout; } public function getProtocol(): array { return $this->protocol; } } src/WebSocket/Frame.php000064400000000553151360554500010773 0ustar00 */ protected array $events = []; public function __construct(Response $connection, Request $request) { $this->connection = $connection; $this->connection->upgrade(); } public function on(string $event, callable $callback): void { $this->events[$event] = $callback; } public function start(): void { while (true) { /** @var false|string|SwFrame $frame */ $frame = $this->connection->recv(); if ($frame === false || $frame instanceof CloseFrame || $frame === '') { if ($callback = $this->events[static::ON_CLOSE] ?? null) { $callback($this->connection, $this->connection->fd); } break; } switch ($frame->opcode) { case Opcode::PING: $this->connection->push('', Opcode::PONG); break; case Opcode::PONG: break; default: if ($callback = $this->events[static::ON_MESSAGE] ?? null) { $callback($this->connection, $frame); } } } $this->connection = null; $this->events = []; } }