add connection manager and facade with implementation
This commit is contained in:
parent
c0bc99c781
commit
ca2238c9b5
|
@ -33,7 +33,10 @@
|
||||||
"laravel": {
|
"laravel": {
|
||||||
"providers": [
|
"providers": [
|
||||||
"PhpMqtt\\Client\\MqttClientServiceProvider"
|
"PhpMqtt\\Client\\MqttClientServiceProvider"
|
||||||
]
|
],
|
||||||
|
"aliases": {
|
||||||
|
"MQTT": "PhpMqtt\\Client\\Facades\\MQTT"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,4 +2,55 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
return [];
|
use PhpMqtt\Client\Repositories\MemoryRepository;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default MQTT Connection
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This setting defines the default MQTT connection returned when requesting
|
||||||
|
| a connection without name from the facade.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default_connection' => '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' => [
|
||||||
|
'host' => env('MQTT_HOST'),
|
||||||
|
'port' => env('MQTT_PORT', 1883),
|
||||||
|
'username' => env('MQTT_USERNAME'),
|
||||||
|
'password' => env('MQTT_PASSWORD'),
|
||||||
|
'client_id' => env('MQTT_CLIENT_ID'),
|
||||||
|
'cafile' => env('MQTT_CAFILE'),
|
||||||
|
'clean_session' => env('MQTT_CLEAN_SESSION', true),
|
||||||
|
'logging_enabled' => env('MQTT_LOGGING', true),
|
||||||
|
'repository' => MemoryRepository::class,
|
||||||
|
'settings' => [
|
||||||
|
'quality_of_service' => env('MQTT_QUALITY_OF_SERVICE', 0),
|
||||||
|
'block_socket' => env('MQTT_BLOCK_SOCKET', false),
|
||||||
|
'keep_alive' => env('MQTT_KEEP_ALIVE', 10),
|
||||||
|
'socket_timeout' => env('MQTT_TIMEOUT', 5),
|
||||||
|
'resend_timeout' => env('MQTT_RESEND_TIMEOUT', 10),
|
||||||
|
'retain' => env('MQTT_RETAIN', false),
|
||||||
|
'last_will_topic' => env('MQTT_WILL_TOPIC'),
|
||||||
|
'last_will_message' => env('MQTT_WILL_MESSAGE'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpMqtt\Client;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||||
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
|
use PhpMqtt\Client\Contracts\Repository;
|
||||||
|
use PhpMqtt\Client\Exceptions\ConnectingToBrokerFailedException;
|
||||||
|
use PhpMqtt\Client\Exceptions\ConnectionNotAvailableException;
|
||||||
|
use PhpMqtt\Client\Exceptions\DataTransferException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages the MQTT connections of the application.
|
||||||
|
*
|
||||||
|
* @package PhpMqtt\Client
|
||||||
|
*/
|
||||||
|
class ConnectionManager
|
||||||
|
{
|
||||||
|
/** @var Application */
|
||||||
|
protected $application;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
protected $defaultConnection;
|
||||||
|
|
||||||
|
/** @var MQTTClient[] */
|
||||||
|
protected $connections = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConnectionManager constructor.
|
||||||
|
*
|
||||||
|
* @param Application $application
|
||||||
|
* @param array $config
|
||||||
|
*/
|
||||||
|
public function __construct(Application $application, array $config)
|
||||||
|
{
|
||||||
|
$this->application = $application;
|
||||||
|
$this->config = $config;
|
||||||
|
$this->defaultConnection = array_get($config, 'default_connection', 'default');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the connection with the specified name.
|
||||||
|
*
|
||||||
|
* @param string|null $name
|
||||||
|
* @return MQTTClient
|
||||||
|
* @throws BindingResolutionException
|
||||||
|
* @throws ConnectingToBrokerFailedException
|
||||||
|
* @throws ConnectionNotAvailableException
|
||||||
|
*/
|
||||||
|
public function connection(string $name = null): MQTTClient
|
||||||
|
{
|
||||||
|
if ($name === null) {
|
||||||
|
$name = $this->defaultConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!array_key_exists($name, $this->connections)) {
|
||||||
|
$this->connections[$name] = $this->createConnection($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->connections[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the given connection if opened.
|
||||||
|
*
|
||||||
|
* @param string|null $connection
|
||||||
|
* @throws DataTransferException
|
||||||
|
*/
|
||||||
|
public function close(string $connection = null): void
|
||||||
|
{
|
||||||
|
if ($connection === null) {
|
||||||
|
$connection = $this->defaultConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array_key_exists($connection, $this->connections)) {
|
||||||
|
$this->connections[$connection]->close();
|
||||||
|
unset($this->connections[$connection]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Publishes a message on the given connection. The QoS level will be 0
|
||||||
|
* and the message will not be retained by the broker.
|
||||||
|
*
|
||||||
|
* @param string $topic
|
||||||
|
* @param string $message
|
||||||
|
* @param string|null $connection
|
||||||
|
* @throws BindingResolutionException
|
||||||
|
* @throws ConnectingToBrokerFailedException
|
||||||
|
* @throws ConnectionNotAvailableException
|
||||||
|
* @throws DataTransferException
|
||||||
|
*/
|
||||||
|
public function publish(string $topic, string $message, string $connection = null): void
|
||||||
|
{
|
||||||
|
$client = $this->connection($connection);
|
||||||
|
|
||||||
|
$client->publish($topic, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new MQTT client and connects to the specified server.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @return MQTTClient
|
||||||
|
* @throws BindingResolutionException
|
||||||
|
* @throws ConnectingToBrokerFailedException
|
||||||
|
* @throws ConnectionNotAvailableException
|
||||||
|
*/
|
||||||
|
protected function createConnection(string $name): MQTTClient
|
||||||
|
{
|
||||||
|
$config = array_get($this->config, "connections.{$name}");
|
||||||
|
if ($config === null) {
|
||||||
|
throw new ConnectionNotAvailableException($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
$host = array_get($config, 'host');
|
||||||
|
$port = array_get($config, 'port', 1883);
|
||||||
|
$username = array_get($config, 'username');
|
||||||
|
$password = array_get($config, 'password');
|
||||||
|
$clientId = array_get($config, 'client_id');
|
||||||
|
$caFile = array_get($config, 'cafile');
|
||||||
|
$cleanSession = array_get($config, 'clean_session', true);
|
||||||
|
$loggingEnabled = array_get($config, 'logging_enabled', true);
|
||||||
|
$repository = array_get($config, 'repository', Repository::class);
|
||||||
|
|
||||||
|
$settings = $this->parseConnectionSettings(array_get($config, 'settings', []));
|
||||||
|
$repository = $this->application->make($repository);
|
||||||
|
$logger = $loggingEnabled ? $this->application->make('log') : null;
|
||||||
|
|
||||||
|
$client = new MQTTClient($host, $port, $clientId, $caFile, $repository, $logger);
|
||||||
|
$client->connect($username, $password, $settings, $cleanSession);
|
||||||
|
|
||||||
|
return $client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given settings and returns a populated settings object.
|
||||||
|
*
|
||||||
|
* @param array $settings
|
||||||
|
* @return ConnectionSettings
|
||||||
|
*/
|
||||||
|
protected function parseConnectionSettings(array $settings): ConnectionSettings
|
||||||
|
{
|
||||||
|
$qos = array_get($settings, 'quality_of_service', 0);
|
||||||
|
$blockSocket = array_get($settings, 'block_socket', false);
|
||||||
|
$keepAlive = array_get($settings, 'keep_alive', 10);
|
||||||
|
$socketTimeout = array_get($settings, 'socket_timeout', 5);
|
||||||
|
$resendTimeout = array_get($settings, 'resend_timeout', 10);
|
||||||
|
$retain = array_get($settings, 'retain', false);
|
||||||
|
$lastWillTopic = array_get($settings, 'last_will_topic');
|
||||||
|
$lastWillMessage = array_get($settings, 'last_will_message');
|
||||||
|
|
||||||
|
return new ConnectionSettings($qos, $retain, $blockSocket, $socketTimeout, $keepAlive, $resendTimeout, $lastWillTopic, $lastWillMessage);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpMqtt\Client\Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ConnectionNotAvailableException
|
||||||
|
*
|
||||||
|
* @package PhpMqtt\Client\Exceptions
|
||||||
|
*/
|
||||||
|
class ConnectionNotAvailableException extends MQTTClientException
|
||||||
|
{
|
||||||
|
public function __construct(string $name)
|
||||||
|
{
|
||||||
|
parent::__construct(sprintf('An MQTT connection with the name [%s] could not be found.', $name));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpMqtt\Client\Facades;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
use PhpMqtt\Client\ConnectionManager;
|
||||||
|
use PhpMqtt\Client\MQTTClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method static MQTTClient connection(string $name = null)
|
||||||
|
* @method static void close(string $connection = null)
|
||||||
|
* @method static void publish(string $topic, string $message, string $connection = null)
|
||||||
|
*
|
||||||
|
* @see ConnectionManager
|
||||||
|
* @package PhpMqtt\Client\Facades
|
||||||
|
*/
|
||||||
|
class MQTT extends Facade
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the registered name of the component.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected static function getFacadeAccessor()
|
||||||
|
{
|
||||||
|
return ConnectionManager::class;
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace PhpMqtt\Client;
|
namespace PhpMqtt\Client;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,23 +12,6 @@ use Illuminate\Support\ServiceProvider;
|
||||||
*/
|
*/
|
||||||
class MqttClientServiceProvider extends ServiceProvider
|
class MqttClientServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Indicates if loading of the provider is deferred.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
protected $defer = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bootstrap the application events.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function boot(): void
|
|
||||||
{
|
|
||||||
$this->handleConfigs();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the service provider.
|
* Register the service provider.
|
||||||
*
|
*
|
||||||
|
@ -35,17 +19,8 @@ class MqttClientServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function register(): void
|
public function register(): void
|
||||||
{
|
{
|
||||||
// Bind any implementations.
|
$this->registerConfig();
|
||||||
}
|
$this->registerServices();
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the services provided by the provider.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function provides(): array
|
|
||||||
{
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,12 +28,27 @@ class MqttClientServiceProvider extends ServiceProvider
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
protected function handleConfigs(): void
|
protected function registerConfig(): void
|
||||||
{
|
{
|
||||||
$configPath = __DIR__ . '/../config/mqtt-client.php';
|
$configPath = __DIR__ . '/../config/mqtt-client.php';
|
||||||
|
|
||||||
$this->publishes([$configPath => config_path('mqtt-client.php')], 'config');
|
if ($this->app->runningInConsole()) {
|
||||||
|
$this->publishes([$configPath => config_path('mqtt-client.php')], 'config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->mergeConfigFrom($configPath, 'mqtt-client');
|
$this->mergeConfigFrom($configPath, 'mqtt-client');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the services offered by this package.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function registerServices(): void
|
||||||
|
{
|
||||||
|
$this->app->bind(ConnectionManager::class, function (Application $app) {
|
||||||
|
$config = $app->make('config')->get('mqtt-client', []);
|
||||||
|
return new ConnectionManager($app, $config);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue