commit ef4a9d4688edebc14d74c2911d5c127b3c4f24db Author: Wenbin.Wang Date: Fri Dec 24 16:21:11 2021 +0800 基于Hyperf实现简易消息推送系统代码上线 diff --git a/hyperf-skeleton/.env.example b/hyperf-skeleton/.env.example new file mode 100644 index 0000000..6879583 --- /dev/null +++ b/hyperf-skeleton/.env.example @@ -0,0 +1,17 @@ +APP_NAME=skeleton +APP_ENV=dev + +DB_DRIVER=mysql +DB_HOST=localhost +DB_PORT=3306 +DB_DATABASE=hyperf +DB_USERNAME=root +DB_PASSWORD= +DB_CHARSET=utf8mb4 +DB_COLLATION=utf8mb4_unicode_ci +DB_PREFIX= + +REDIS_HOST=localhost +REDIS_AUTH=(null) +REDIS_PORT=6379 +REDIS_DB=0 \ No newline at end of file diff --git a/hyperf-skeleton/.gitignore b/hyperf-skeleton/.gitignore new file mode 100644 index 0000000..c867e8f --- /dev/null +++ b/hyperf-skeleton/.gitignore @@ -0,0 +1,13 @@ +.buildpath +.settings/ +.project +*.patch +.idea/ +.git/ +runtime/ +vendor/ +.phpintel/ +.env +.DS_Store +*.lock +.phpunit* \ No newline at end of file diff --git a/hyperf-skeleton/Dockerfile b/hyperf-skeleton/Dockerfile new file mode 100644 index 0000000..c21ffb4 --- /dev/null +++ b/hyperf-skeleton/Dockerfile @@ -0,0 +1,60 @@ +# Default Dockerfile +# +# @link https://www.hyperf.io +# @document https://hyperf.wiki +# @contact group@hyperf.io +# @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE + +FROM hyperf/hyperf:7.4-alpine-v3.11-cli +LABEL maintainer="Hyperf Developers " version="1.0" license="MIT" app.name="Hyperf" + +## +# ---------- env settings ---------- +## +# --build-arg timezone=Asia/Shanghai +ARG timezone + +ENV TIMEZONE=${timezone:-"Asia/Shanghai"} \ + COMPOSER_VERSION=1.10.10 \ + APP_ENV=prod \ + SCAN_CACHEABLE=(true) + +# update +RUN set -ex \ + # install composer + && cd /tmp \ + && wget https://github.com/composer/composer/releases/download/${COMPOSER_VERSION}/composer.phar \ + && chmod u+x composer.phar \ + && mv composer.phar /usr/local/bin/composer \ + # show php version and extensions + && php -v \ + && php -m \ + && php --ri swoole \ + # ---------- some config ---------- + && cd /etc/php7 \ + # - 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 + +# Composer Cache +# COPY ./composer.* /opt/www/ +# RUN composer install --no-dev --no-scripts + +COPY . /opt/www +RUN composer install --no-dev -o && php bin/hyperf.php + +EXPOSE 9501 + +ENTRYPOINT ["php", "/opt/www/bin/hyperf.php", "start"] diff --git a/hyperf-skeleton/README.md b/hyperf-skeleton/README.md new file mode 100644 index 0000000..0d858eb --- /dev/null +++ b/hyperf-skeleton/README.md @@ -0,0 +1,36 @@ +# Introduction + +This is a skeleton application using the Hyperf framework. This application is meant to be used as a starting place for those looking to get their feet wet with Hyperf Framework. + +# Requirements + +Hyperf has some requirements for the system environment, it can only run under Linux and Mac environment, but due to the development of Docker virtualization technology, Docker for Windows can also be used as the running environment under Windows. + +The various versions of Dockerfile have been prepared for you in the [hyperf\hyperf-docker](https://github.com/hyperf/hyperf-docker) project, or directly based on the already built [hyperf\hyperf](https://hub.docker.com/r/hyperf/hyperf) Image to run. + +When you don't want to use Docker as the basis for your running environment, you need to make sure that your operating environment meets the following requirements: + + - PHP >= 7.2 + - Swoole PHP extension >= 4.4,and Disabled `Short Name` + - OpenSSL PHP extension + - JSON PHP extension + - PDO PHP extension (If you need to use MySQL Client) + - Redis PHP extension (If you need to use Redis Client) + - Protobuf PHP extension (If you need to use gRPC Server of Client) + +# Installation using Composer + +The easiest way to create a new Hyperf project is to use Composer. If you don't have it already installed, then please install as per the documentation. + +To create your new Hyperf project: + +$ composer create-project hyperf/hyperf-skeleton path/to/install + +Once installed, you can run the server immediately using the command below. + +$ cd path/to/install +$ php bin/hyperf.php start + +This will start the cli-server on port `9501`, and bind it to all network interfaces. You can then visit the site at `http://localhost:9501/` + +which will bring up Hyperf default home page. diff --git a/hyperf-skeleton/app/Amqp/Consumer/DemoConsumer.php b/hyperf-skeleton/app/Amqp/Consumer/DemoConsumer.php new file mode 100644 index 0000000..fd5f7e1 --- /dev/null +++ b/hyperf-skeleton/app/Amqp/Consumer/DemoConsumer.php @@ -0,0 +1,36 @@ +container->get(\Redis::class); + $fdList = $redis->sMembers('websocket_sjd_1'); + + $server = $this->container->get(ServerFactory::class)->getServer()->getServer(); + foreach ($fdList as $fd) { + if (!empty($fd)) { + $server->push((int)$fd, $data); + } + } + + return Result::ACK; + } +} diff --git a/hyperf-skeleton/app/Amqp/Producer/DemoProducer.php b/hyperf-skeleton/app/Amqp/Producer/DemoProducer.php new file mode 100644 index 0000000..eebbead --- /dev/null +++ b/hyperf-skeleton/app/Amqp/Producer/DemoProducer.php @@ -0,0 +1,22 @@ +poolName = 'default'; + + // 具体丢入队列中的信息 + $this->payload = $data; + } +} diff --git a/hyperf-skeleton/app/Constants/ErrorCode.php b/hyperf-skeleton/app/Constants/ErrorCode.php new file mode 100644 index 0000000..1dfec21 --- /dev/null +++ b/hyperf-skeleton/app/Constants/ErrorCode.php @@ -0,0 +1,26 @@ +request->input('user', 'Hyperf'); + $method = $this->request->getMethod(); + + return [ + 'method' => $method, + 'message' => "Hello {$user}.", + ]; + } +} diff --git a/hyperf-skeleton/app/Controller/MainController.php b/hyperf-skeleton/app/Controller/MainController.php new file mode 100644 index 0000000..3c5d3fc --- /dev/null +++ b/hyperf-skeleton/app/Controller/MainController.php @@ -0,0 +1,45 @@ +request->input('name', 'Hyperf'); + $num = $this->request->input('num', 'test12345'); + $door = $this->request->input('door', '办公室'); + + $data = [ + 'code' => 200, + 'data' => [ + 'userOutName' => $name, + 'userOutNum' => $num, + 'recordOutTime' => date('Y-m-d H:i:s'), + 'doorOutName' => $door + ] + ]; + $data = json_encode($data); + // 组装队列消息 + $message = new DemoProducer($data); + // 通过容器获取队列生产者实例 + $producer = ApplicationContext::getContainer()->get(Producer::class); + // 生产消息 + $result = $producer->produce($message); + var_dump($result); + + return [ + 'code' => 200, + 'msg' => "Push success!", + ]; + } +} diff --git a/hyperf-skeleton/app/Controller/WebSocketController.php b/hyperf-skeleton/app/Controller/WebSocketController.php new file mode 100644 index 0000000..ab66e27 --- /dev/null +++ b/hyperf-skeleton/app/Controller/WebSocketController.php @@ -0,0 +1,66 @@ +container->get(\Redis::class); + // 获取所有的客户端id + $fdList = $redis->sMembers('websocket_sjd_1'); + // 如果当前客户端在客户端集合中,就刷新 + if (in_array($frame->fd, $fdList)) { + $redis->sAdd('websocket_sjd_1', $frame->fd); + $redis->expire('websocket_sjd_1', 7200); + } + + // push消息给客户端 + $server->push($frame->fd, json_encode(['Recv' => $frame->data])); + } + + /** + * 客户端失去连接 + * @param $server + * @param int $fd + * @param int $reactorId + */ + public function onClose($server, int $fd, int $reactorId): void + { + $redis = $this->container->get(\Redis::class); + // 移除集合中指定的value + $redis->sRem('websocket_sjd_1', $fd); + echo 'closed'; + } + + /** + * 客户端连接开启 + * @param $server + * @param Request $request + */ + public function onOpen($server, Request $request): void + { + $redis = $this->container->get(\Redis::class); + // 保存客户端id + $resAdd = $redis->sAdd('websocket_sjd_1', $request->fd); + var_dump($resAdd); + + $resExp = $redis->expire('websocket_sjd_1', 7200); + var_dump($resExp); + + // push消息给客户端 + $server->push($request->fd, json_encode(['Status' => 'Opened'])); + } +} diff --git a/hyperf-skeleton/app/Exception/BusinessException.php b/hyperf-skeleton/app/Exception/BusinessException.php new file mode 100644 index 0000000..eaae4aa --- /dev/null +++ b/hyperf-skeleton/app/Exception/BusinessException.php @@ -0,0 +1,28 @@ +logger = $logger; + } + + public function handle(Throwable $throwable, ResponseInterface $response) + { + $this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile())); + $this->logger->error($throwable->getTraceAsString()); + return $response->withHeader('Server', 'Hyperf')->withStatus(500)->withBody(new SwooleStream('Internal Server Error.')); + } + + public function isValid(Throwable $throwable): bool + { + return true; + } +} diff --git a/hyperf-skeleton/app/Listener/DbQueryExecutedListener.php b/hyperf-skeleton/app/Listener/DbQueryExecutedListener.php new file mode 100644 index 0000000..abe5a52 --- /dev/null +++ b/hyperf-skeleton/app/Listener/DbQueryExecutedListener.php @@ -0,0 +1,61 @@ +logger = $container->get(LoggerFactory::class)->get('sql'); + } + + public function listen(): array + { + return [ + QueryExecuted::class, + ]; + } + + /** + * @param QueryExecuted $event + */ + public function process(object $event) + { + if ($event instanceof QueryExecuted) { + $sql = $event->sql; + if (! Arr::isAssoc($event->bindings)) { + foreach ($event->bindings as $key => $value) { + $sql = Str::replaceFirst('?', "'{$value}'", $sql); + } + } + + $this->logger->info(sprintf('[%s] %s', $event->time, $sql)); + } + } +} diff --git a/hyperf-skeleton/app/Listener/QueueHandleListener.php b/hyperf-skeleton/app/Listener/QueueHandleListener.php new file mode 100644 index 0000000..56d9c3a --- /dev/null +++ b/hyperf-skeleton/app/Listener/QueueHandleListener.php @@ -0,0 +1,79 @@ +logger = $loggerFactory->get('queue'); + $this->formatter = $formatter; + } + + public function listen(): array + { + return [ + AfterHandle::class, + BeforeHandle::class, + FailedHandle::class, + RetryHandle::class, + ]; + } + + public function process(object $event) + { + if ($event instanceof Event && $event->message->job()) { + $job = $event->message->job(); + $jobClass = get_class($job); + $date = date('Y-m-d H:i:s'); + + switch (true) { + case $event instanceof BeforeHandle: + $this->logger->info(sprintf('[%s] Processing %s.', $date, $jobClass)); + break; + case $event instanceof AfterHandle: + $this->logger->info(sprintf('[%s] Processed %s.', $date, $jobClass)); + break; + case $event instanceof FailedHandle: + $this->logger->error(sprintf('[%s] Failed %s.', $date, $jobClass)); + $this->logger->error($this->formatter->format($event->getThrowable())); + break; + case $event instanceof RetryHandle: + $this->logger->warning(sprintf('[%s] Retried %s.', $date, $jobClass)); + break; + } + } + } +} diff --git a/hyperf-skeleton/app/Model/Model.php b/hyperf-skeleton/app/Model/Model.php new file mode 100644 index 0000000..fe03061 --- /dev/null +++ b/hyperf-skeleton/app/Model/Model.php @@ -0,0 +1,18 @@ +get(\Hyperf\Contract\ApplicationInterface::class); + $application->run(); +})(); diff --git a/hyperf-skeleton/composer.json b/hyperf-skeleton/composer.json new file mode 100644 index 0000000..5636c20 --- /dev/null +++ b/hyperf-skeleton/composer.json @@ -0,0 +1,80 @@ +{ + "name": "hyperf/hyperf-skeleton", + "type": "project", + "keywords": [ + "php", + "swoole", + "framework", + "hyperf", + "microservice", + "middleware" + ], + "description": "A coroutine framework that focuses on hyperspeed and flexible, specifically use for build microservices and middlewares.", + "license": "Apache-2.0", + "require": { + "php": ">=7.2", + "ext-json": "*", + "ext-redis": "*", + "ext-swoole": ">=4.5", + "hyperf/cache": "~2.0.0", + "hyperf/command": "~2.0.0", + "hyperf/config": "~2.0.0", + "hyperf/db-connection": "~2.0.0", + "hyperf/framework": "~2.0.0", + "hyperf/guzzle": "~2.0.0", + "hyperf/http-server": "~2.0.0", + "hyperf/logger": "~2.0.0", + "hyperf/memory": "~2.0.0", + "hyperf/process": "~2.0.0", + "hyperf/redis": "~2.0.0", + "hyperf/json-rpc": "~2.0.0", + "hyperf/rpc": "~2.0.0", + "hyperf/rpc-client": "~2.0.0", + "hyperf/rpc-server": "~2.0.0", + "hyperf/constants": "~2.0.0", + "hyperf/async-queue": "~2.0.0", + "hyperf/amqp": "~2.0.0", + "hyperf/websocket-server": "^2.0" + }, + "require-dev": { + "swoole/ide-helper": "^4.5", + "friendsofphp/php-cs-fixer": "^2.14", + "mockery/mockery": "^1.0", + "phpstan/phpstan": "^0.12", + "hyperf/devtool": "~2.0.0", + "hyperf/testing": "~2.0.0" + }, + "suggest": { + "ext-openssl": "Required to use HTTPS.", + "ext-json": "Required to use JSON.", + "ext-pdo": "Required to use MySQL Client.", + "ext-pdo_mysql": "Required to use MySQL Client.", + "ext-redis": "Required to use Redis Client." + }, + "autoload": { + "psr-4": { + "App\\": "app/" + }, + "files": [] + }, + "autoload-dev": { + "psr-4": { + "HyperfTest\\": "./test/" + } + }, + "minimum-stability": "dev", + "prefer-stable": true, + "extra": [], + "scripts": { + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-autoload-dump": [ + "rm -rf runtime/container" + ], + "test": "co-phpunit -c phpunit.xml --colors=always", + "cs-fix": "php-cs-fixer fix $1", + "analyse": "phpstan analyse --memory-limit 300M -l 0 -c phpstan.neon ./app ./config", + "start": "php ./bin/hyperf.php start" + } +} diff --git a/hyperf-skeleton/config/autoload/amqp.php b/hyperf-skeleton/config/autoload/amqp.php new file mode 100644 index 0000000..3c4cc94 --- /dev/null +++ b/hyperf-skeleton/config/autoload/amqp.php @@ -0,0 +1,38 @@ + [ + 'host' => 'localhost', + 'port' => 5672, + 'user' => 'guest', + 'password' => 'guest', + 'vhost' => '/', + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + ], + 'params' => [ + 'insist' => false, + 'login_method' => 'AMQPLAIN', + 'login_response' => null, + 'locale' => 'en_US', + 'connection_timeout' => 3.0, + 'read_write_timeout' => 6.0, + 'context' => null, + 'keepalive' => false, + 'heartbeat' => 3, + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/annotations.php b/hyperf-skeleton/config/autoload/annotations.php new file mode 100644 index 0000000..1423a25 --- /dev/null +++ b/hyperf-skeleton/config/autoload/annotations.php @@ -0,0 +1,21 @@ + [ + 'paths' => [ + BASE_PATH . '/app', + ], + 'ignore_annotations' => [ + 'mixin', + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/aspects.php b/hyperf-skeleton/config/autoload/aspects.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/hyperf-skeleton/config/autoload/aspects.php @@ -0,0 +1,13 @@ + [ + 'driver' => Hyperf\AsyncQueue\Driver\RedisDriver::class, + 'channel' => 'queue', + 'timeout' => 2, + 'retry_seconds' => 5, + 'handle_timeout' => 10, + 'processes' => 1, + ], +]; diff --git a/hyperf-skeleton/config/autoload/cache.php b/hyperf-skeleton/config/autoload/cache.php new file mode 100644 index 0000000..def82eb --- /dev/null +++ b/hyperf-skeleton/config/autoload/cache.php @@ -0,0 +1,18 @@ + [ + 'driver' => Hyperf\Cache\Driver\RedisDriver::class, + 'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class, + 'prefix' => 'c:', + ], +]; diff --git a/hyperf-skeleton/config/autoload/commands.php b/hyperf-skeleton/config/autoload/commands.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/hyperf-skeleton/config/autoload/commands.php @@ -0,0 +1,13 @@ + [ + 'driver' => env('DB_DRIVER', 'mysql'), + 'host' => env('DB_HOST', 'localhost'), + 'database' => env('DB_DATABASE', 'hyperf'), + 'port' => env('DB_PORT', 3306), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'collation' => env('DB_COLLATION', 'utf8_unicode_ci'), + 'prefix' => env('DB_PREFIX', ''), + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60), + ], + 'commands' => [ + 'gen:model' => [ + 'path' => 'app/Model', + 'force_casts' => true, + 'inheritance' => 'Model', + ], + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/dependencies.php b/hyperf-skeleton/config/autoload/dependencies.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/hyperf-skeleton/config/autoload/dependencies.php @@ -0,0 +1,13 @@ + [ + 'amqp' => [ + 'consumer' => [ + 'namespace' => 'App\\Amqp\\Consumer', + ], + 'producer' => [ + 'namespace' => 'App\\Amqp\\Producer', + ], + ], + 'aspect' => [ + 'namespace' => 'App\\Aspect', + ], + 'command' => [ + 'namespace' => 'App\\Command', + ], + 'controller' => [ + 'namespace' => 'App\\Controller', + ], + 'job' => [ + 'namespace' => 'App\\Job', + ], + 'listener' => [ + 'namespace' => 'App\\Listener', + ], + 'middleware' => [ + 'namespace' => 'App\\Middleware', + ], + 'Process' => [ + 'namespace' => 'App\\Processes', + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/exceptions.php b/hyperf-skeleton/config/autoload/exceptions.php new file mode 100644 index 0000000..b848177 --- /dev/null +++ b/hyperf-skeleton/config/autoload/exceptions.php @@ -0,0 +1,19 @@ + [ + 'http' => [ + Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class, + App\Exception\Handler\AppExceptionHandler::class, + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/listeners.php b/hyperf-skeleton/config/autoload/listeners.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/hyperf-skeleton/config/autoload/listeners.php @@ -0,0 +1,13 @@ + [ + 'handler' => [ + 'class' => Monolog\Handler\StreamHandler::class, + 'constructor' => [ + 'stream' => BASE_PATH . '/runtime/logs/hyperf.log', + 'level' => Monolog\Logger::DEBUG, + ], + ], + 'formatter' => [ + 'class' => Monolog\Formatter\LineFormatter::class, + 'constructor' => [ + 'format' => null, + 'dateFormat' => 'Y-m-d H:i:s', + 'allowInlineLineBreaks' => true, + ], + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/middlewares.php b/hyperf-skeleton/config/autoload/middlewares.php new file mode 100644 index 0000000..49bdec2 --- /dev/null +++ b/hyperf-skeleton/config/autoload/middlewares.php @@ -0,0 +1,15 @@ + [ + ], +]; diff --git a/hyperf-skeleton/config/autoload/processes.php b/hyperf-skeleton/config/autoload/processes.php new file mode 100644 index 0000000..f46bd96 --- /dev/null +++ b/hyperf-skeleton/config/autoload/processes.php @@ -0,0 +1,13 @@ + [ + 'host' => env('REDIS_HOST', 'localhost'), + 'auth' => env('REDIS_AUTH', null), + 'port' => (int) env('REDIS_PORT', 6379), + 'db' => (int) env('REDIS_DB', 0), + 'pool' => [ + 'min_connections' => 1, + 'max_connections' => 10, + 'connect_timeout' => 10.0, + 'wait_timeout' => 3.0, + 'heartbeat' => -1, + 'max_idle_time' => (float) env('REDIS_MAX_IDLE_TIME', 60), + ], + ], +]; diff --git a/hyperf-skeleton/config/autoload/server.php b/hyperf-skeleton/config/autoload/server.php new file mode 100644 index 0000000..2664006 --- /dev/null +++ b/hyperf-skeleton/config/autoload/server.php @@ -0,0 +1,57 @@ + SWOOLE_PROCESS, + 'servers' => [ + [ + 'name' => 'http', + 'type' => Server::SERVER_HTTP, + 'host' => '0.0.0.0', + 'port' => 9501, + 'sock_type' => SWOOLE_SOCK_TCP, + 'callbacks' => [ + SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'], + ], + ], + [ + 'name' => 'ws', + 'type' => Server::SERVER_WEBSOCKET, + 'host' => '0.0.0.0', + 'port' => 9502, + 'sock_type' => SWOOLE_SOCK_TCP, + 'callbacks' => [ + SwooleEvent::ON_HAND_SHAKE => [Hyperf\WebSocketServer\Server::class, 'onHandShake'], + SwooleEvent::ON_MESSAGE => [Hyperf\WebSocketServer\Server::class, 'onMessage'], + SwooleEvent::ON_CLOSE => [Hyperf\WebSocketServer\Server::class, 'onClose'], + ], + ], + ], + 'settings' => [ + 'enable_coroutine' => true, + 'worker_num' => swoole_cpu_num(), + 'pid_file' => BASE_PATH . '/runtime/hyperf.pid', + 'open_tcp_nodelay' => true, + 'max_coroutine' => 100000, + 'open_http2_protocol' => true, + 'max_request' => 100000, + 'socket_buffer_size' => 2 * 1024 * 1024, + 'buffer_output_size' => 2 * 1024 * 1024, + ], + 'callbacks' => [ + SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], + SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], + SwooleEvent::ON_WORKER_EXIT => [Hyperf\Framework\Bootstrap\WorkerExitCallback::class, 'onWorkerExit'], + ], +]; diff --git a/hyperf-skeleton/config/autoload/services.php b/hyperf-skeleton/config/autoload/services.php new file mode 100644 index 0000000..656b616 --- /dev/null +++ b/hyperf-skeleton/config/autoload/services.php @@ -0,0 +1,29 @@ + [ + [ + // The service name, this name should as same as with the name of service provider. + 'name' => 'YourServiceName', + // The service registry, if `nodes` is missing below, then you should provide this configs. + 'registry' => [ + 'protocol' => 'consul', + 'address' => 'Enter the address of service registry', + ], + // If `registry` is missing, then you should provide the nodes configs. + 'nodes' => [ + // Provide the host and port of the service provider. + // ['host' => 'The host of the service provider', 'port' => 9502] + ], + ], + ], +]; diff --git a/hyperf-skeleton/config/config.php b/hyperf-skeleton/config/config.php new file mode 100644 index 0000000..38823e0 --- /dev/null +++ b/hyperf-skeleton/config/config.php @@ -0,0 +1,31 @@ + env('APP_NAME', 'skeleton'), + 'app_env' => env('APP_ENV', 'dev'), + 'scan_cacheable' => env('SCAN_CACHEABLE', false), + StdoutLoggerInterface::class => [ + 'log_level' => [ + LogLevel::ALERT, + LogLevel::CRITICAL, + LogLevel::DEBUG, + LogLevel::EMERGENCY, + LogLevel::ERROR, + LogLevel::INFO, + LogLevel::NOTICE, + LogLevel::WARNING, + ], + ], +]; diff --git a/hyperf-skeleton/config/container.php b/hyperf-skeleton/config/container.php new file mode 100644 index 0000000..2a09133 --- /dev/null +++ b/hyperf-skeleton/config/container.php @@ -0,0 +1,24 @@ + + + + + ./test + + + + + ./app + + + diff --git a/hyperf-skeleton/test/Cases/ExampleTest.php b/hyperf-skeleton/test/Cases/ExampleTest.php new file mode 100644 index 0000000..6f28d24 --- /dev/null +++ b/hyperf-skeleton/test/Cases/ExampleTest.php @@ -0,0 +1,27 @@ +assertTrue(true); + $this->assertTrue(is_array($this->get('/'))); + } +} diff --git a/hyperf-skeleton/test/HttpTestCase.php b/hyperf-skeleton/test/HttpTestCase.php new file mode 100644 index 0000000..cabfcbf --- /dev/null +++ b/hyperf-skeleton/test/HttpTestCase.php @@ -0,0 +1,42 @@ +client = make(Client::class); + } + + public function __call($name, $arguments) + { + return $this->client->{$name}(...$arguments); + } +} diff --git a/hyperf-skeleton/test/bootstrap.php b/hyperf-skeleton/test/bootstrap.php new file mode 100644 index 0000000..8396ecb --- /dev/null +++ b/hyperf-skeleton/test/bootstrap.php @@ -0,0 +1,29 @@ +get(Hyperf\Contract\ApplicationInterface::class); diff --git a/ws.html b/ws.html new file mode 100644 index 0000000..4cd7d2c --- /dev/null +++ b/ws.html @@ -0,0 +1,211 @@ + + + + +简易WebSocket消息推送系统 + + + + + +

简易WebSocket消息推送系统

+
+ + + + + + + + + + + +
时间姓名学工号地点
+
+ + + + + \ No newline at end of file