From df73ceea1b4aa50ce6b50eb17a35c985cf4a135e Mon Sep 17 00:00:00 2001 From: "iVampireSP.com" Date: Wed, 23 Nov 2022 21:23:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=B9=E8=BF=9B=20=E4=BF=9D=E7=95=99=204=20?= =?UTF-8?q?=E4=BD=8D=E5=B0=8F=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Console/Commands/Mqtt.php | 125 +++++++++++++++++++++ app/Models/Host.php | 2 +- composer.json | 1 + composer.lock | 202 +++++++++++++++++++++++++++++++++- config/mqtt-client.php | 118 ++++++++++++++++++++ 5 files changed, 446 insertions(+), 2 deletions(-) create mode 100644 app/Console/Commands/Mqtt.php create mode 100644 config/mqtt-client.php diff --git a/app/Console/Commands/Mqtt.php b/app/Console/Commands/Mqtt.php new file mode 100644 index 0000000..372d35b --- /dev/null +++ b/app/Console/Commands/Mqtt.php @@ -0,0 +1,125 @@ +info('Stopping...'); + // 关闭子进程 + posix_kill($pid, SIGKILL); + exit; + }); + + // MQTT::publish('some/topic', 'Hello World!'); + + $tasks = [ + 'publish' => function () { + $this->info('Publishing...'); + + MqttClient::publish('some/topic', 'Hello World!'); + + sleep(1); + + + return true; + }, + 'subscribe' => function () { + $this->info('Subscribing...'); + + $mqtt = MqttClient::connection(); + $mqtt->subscribe('some/topic', function (string $topic, string $message) { + echo sprintf('Received QoS level 1 message on topic [%s]: %s', $topic, $message) . PHP_EOL; + }, 1); + $mqtt->loop(true); + + return true; + }, + ]; + + + foreach ($tasks as $key => $task) { + $this->info('Starting task: ' . $key); + $pid = pcntl_fork(); + if ($pid == -1) { + die('could not fork'); + } else if ($pid) { + // we are the parent + // pcntl_wait($status); //Protect against Zombie children + + + // while (pcntl_waitpid(0, $status) != -1) { + // $status = pcntl_wexitstatus($status); + // echo "Child $status completed\n"; + // } + } else { + // we are the child + while (true) { + if ($task() === false) { + break; + } + } + exit(0); + } + } + + + + + return Command::SUCCESS; + + // // 开启新的进程,处理 MQTT 消息 + // $running = 0; // 记录正在运行的子进程数 + // for ($i = 0; $i < $task_num; $i++) { + // $pid = pcntl_fork(); + // if ($pid == -1) { + // die('could not fork'); + // } else if ($pid) { + // $running++; // 进程数+1 + // if ($running >= $max_process) { // 子进程开启数量达到上限 + // pcntl_wait($status); // 等待有子进程退出 + // $running--; // 有子进程退出,进程数-1 + // } + // } else { + // // 子进程 + // echo "子进程开始" . PHP_EOL; + // while (true) { + // MqttClient::publish('some/topic', 'Hello World!'); + // // sleep(0.5); + // } + // } + // } + + // while ($running) { + // pcntl_wait($status); + // $running--; + // } + + + } +} diff --git a/app/Models/Host.php b/app/Models/Host.php index d905b05..353833b 100644 --- a/app/Models/Host.php +++ b/app/Models/Host.php @@ -316,7 +316,7 @@ public function cost($amount = null, $auto = true): bool return true; } - $real_price = round($real_price ?? 0, 8); + $real_price = round($real_price ?? 0, 4); $transaction = new Transaction(); diff --git a/composer.json b/composer.json index 706f004..7ef214a 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,7 @@ "laravel/octane": "^1.3", "laravel/sanctum": "^3.0", "laravel/tinker": "^2.7", + "php-mqtt/laravel-client": "^1.1", "pusher/pusher-php-server": "^7.2", "spiral/roadrunner": "^2.8.2", "symfony/psr-http-message-bridge": "^2.1", diff --git a/composer.lock b/composer.lock index b8ffc71..356d583 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6d925a2d2bb0d0c62b8cc85675e99772", + "content-hash": "23878130d9df24ca7447ac251b904417", "packages": [ { "name": "brick/math", @@ -2919,6 +2919,72 @@ ], "time": "2022-07-24T11:55:47+00:00" }, + { + "name": "myclabs/php-enum", + "version": "1.8.3", + "source": { + "type": "git", + "url": "https://github.com/myclabs/php-enum.git", + "reference": "b942d263c641ddb5190929ff840c68f78713e937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937", + "reference": "b942d263c641ddb5190929ff840c68f78713e937", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "ext-json": "*", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "1.*", + "vimeo/psalm": "^4.6.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "MyCLabs\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP Enum contributors", + "homepage": "https://github.com/myclabs/php-enum/graphs/contributors" + } + ], + "description": "PHP Enum implementation", + "homepage": "http://github.com/myclabs/php-enum", + "keywords": [ + "enum" + ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.3" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum", + "type": "tidelift" + } + ], + "time": "2021-07-05T08:18:36+00:00" + }, { "name": "nesbot/carbon", "version": "2.62.1", @@ -3488,6 +3554,140 @@ }, "time": "2022-09-26T03:40:35+00:00" }, + { + "name": "php-mqtt/client", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/php-mqtt/client.git", + "reference": "22a207edef01d5f0ed3a6a79565cc425b678d786" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mqtt/client/zipball/22a207edef01d5f0ed3a6a79565cc425b678d786", + "reference": "22a207edef01d5f0ed3a6a79565cc425b678d786", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "myclabs/php-enum": "^1.7", + "php": "^7.4|^8.0", + "psr/log": "^1.1|^2.0|^3.0" + }, + "require-dev": { + "phpunit/php-invoker": "^3.0", + "phpunit/phpunit": "^9.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-redis": "Required for the RedisRepository" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpMqtt\\Client\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marvin Mall", + "email": "marvin-mall@msn.com", + "role": "developer" + } + ], + "description": "An MQTT client written in and for PHP.", + "keywords": [ + "client", + "mqtt", + "publish", + "subscribe" + ], + "support": { + "issues": "https://github.com/php-mqtt/client/issues", + "source": "https://github.com/php-mqtt/client/tree/v1.6.0" + }, + "time": "2022-11-01T20:00:19+00:00" + }, + { + "name": "php-mqtt/laravel-client", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-mqtt/laravel-client.git", + "reference": "d2a2a839e4c8d15ffb1b0caa35219b6f73483a7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-mqtt/laravel-client/zipball/d2a2a839e4c8d15ffb1b0caa35219b6f73483a7d", + "reference": "d2a2a839e4c8d15ffb1b0caa35219b6f73483a7d", + "shasum": "", + "mirrors": [ + { + "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", + "preferred": true + } + ] + }, + "require": { + "illuminate/config": "~7.0|~8.0|~9.0", + "illuminate/support": "~7.0|~8.0|~9.0", + "php": "^7.4|^8.0", + "php-mqtt/client": "^1.0" + }, + "require-dev": { + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "PhpMqtt\\Client\\MqttClientServiceProvider" + ], + "aliases": { + "MQTT": "PhpMqtt\\Client\\Facades\\MQTT" + } + } + }, + "autoload": { + "psr-4": { + "PhpMqtt\\Client\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marvin Mall", + "email": "marvin-mall@msn.com", + "role": "developer" + } + ], + "description": "A wrapper for the php-mqtt/client library for Laravel.", + "homepage": "https://github.com/php-mqtt/laravel-client", + "keywords": [ + "client", + "laravel", + "mqtt", + "publish", + "subscribe" + ], + "support": { + "issues": "https://github.com/php-mqtt/laravel-client/issues", + "source": "https://github.com/php-mqtt/laravel-client/tree/v1.1.0" + }, + "time": "2022-11-22T21:32:07+00:00" + }, { "name": "phpoption/phpoption", "version": "1.8.1", diff --git a/config/mqtt-client.php b/config/mqtt-client.php new file mode 100644 index 0000000..eadad4d --- /dev/null +++ b/config/mqtt-client.php @@ -0,0 +1,118 @@ + 'default', + + /* + |-------------------------------------------------------------------------- + | MQTT Connections + |-------------------------------------------------------------------------- + | + | These are the MQTT connections used by the application. You can also open + | an individual connection from the application itself, but all connections + | defined here can be accessed via name conveniently. + | + */ + + 'connections' => [ + + 'default' => [ + + // The host and port to which the client shall connect. + 'host' => env('MQTT_HOST'), + 'port' => env('MQTT_PORT', 1883), + + // The MQTT protocol version used for the connection. + 'protocol' => MqttClient::MQTT_3_1, + + // A specific client id to be used for the connection. If omitted, + // a random client id will be generated for each new connection. + 'client_id' => 'lae-' . uniqid(), + + // Whether a clean session shall be used and requested by the client. + // A clean session will let the broker forget about subscriptions and + // queued messages when the client disconnects. Also, if available, + // data of a previous session will be deleted when connecting. + 'use_clean_session' => env('MQTT_CLEAN_SESSION', true), + + // Whether logging shall be enabled. The default logger will be used + // with the log level as configured. + 'enable_logging' => env('MQTT_ENABLE_LOGGING', true), + + // Defines which repository implementation shall be used. Currently, + // only a MemoryRepository is supported. + 'repository' => MemoryRepository::class, + + // Additional settings used for the connection to the broker. + // All of these settings are entirely optional and have sane defaults. + 'connection_settings' => [ + + // The TLS settings used for the connection. Must match the specified port. + 'tls' => [ + 'enabled' => env('MQTT_TLS_ENABLED', false), + 'allow_self_signed_certificate' => env('MQTT_TLS_ALLOW_SELF_SIGNED_CERT', false), + 'verify_peer' => env('MQTT_TLS_VERIFY_PEER', true), + 'verify_peer_name' => env('MQTT_TLS_VERIFY_PEER_NAME', true), + 'ca_file' => env('MQTT_TLS_CA_FILE'), + 'ca_path' => env('MQTT_TLS_CA_PATH'), + 'client_certificate_file' => env('MQTT_TLS_CLIENT_CERT_FILE'), + 'client_certificate_key_file' => env('MQTT_TLS_CLIENT_CERT_KEY_FILE'), + 'client_certificate_key_passphrase' => env('MQTT_TLS_CLIENT_CERT_KEY_PASSPHRASE'), + ], + + // Credentials used for authentication and authorization. + 'auth' => [ + 'username' => env('MQTT_AUTH_USERNAME'), + 'password' => env('MQTT_AUTH_PASSWORD'), + ], + + // Can be used to declare a last will during connection. The last will + // is published by the broker when the client disconnects abnormally + // (e.g. in case of a disconnect). + 'last_will' => [ + 'topic' => env('MQTT_LAST_WILL_TOPIC'), + 'message' => env('MQTT_LAST_WILL_MESSAGE'), + 'quality_of_service' => env('MQTT_LAST_WILL_QUALITY_OF_SERVICE', 0), + 'retain' => env('MQTT_LAST_WILL_RETAIN', false), + ], + + // The timeouts (in seconds) used for the connection. Some of these settings + // are only relevant when using the event loop of the MQTT client. + 'connect_timeout' => env('MQTT_CONNECT_TIMEOUT', 60), + 'socket_timeout' => env('MQTT_SOCKET_TIMEOUT', 5), + 'resend_timeout' => env('MQTT_RESEND_TIMEOUT', 10), + + // The interval (in seconds) in which the client will send a ping to the broker, + // if no other message has been sent. + 'keep_alive_interval' => env('MQTT_KEEP_ALIVE_INTERVAL', 10), + + // Additional settings for the optional auto-reconnect. The delay between reconnect attempts is in seconds. + 'auto_reconnect' => [ + 'enabled' => env('MQTT_AUTO_RECONNECT_ENABLED', false), + 'max_reconnect_attempts' => env('MQTT_AUTO_RECONNECT_MAX_RECONNECT_ATTEMPTS', 3), + 'delay_between_reconnect_attempts' => env('MQTT_AUTO_RECONNECT_DELAY_BETWEEN_RECONNECT_ATTEMPTS', 0), + ], + + ], + + ], + + ], + +];