Skip to content

Commit ca2238c

Browse files
committed
add connection manager and facade with implementation
1 parent c0bc99c commit ca2238c

File tree

6 files changed

+284
-32
lines changed

6 files changed

+284
-32
lines changed

composer.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@
3333
"laravel": {
3434
"providers": [
3535
"PhpMqtt\\Client\\MqttClientServiceProvider"
36-
]
36+
],
37+
"aliases": {
38+
"MQTT": "PhpMqtt\\Client\\Facades\\MQTT"
39+
}
3740
}
3841
}
39-
}
42+
}

config/mqtt-client.php

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,55 @@
22

33
declare(strict_types=1);
44

5-
return [];
5+
use PhpMqtt\Client\Repositories\MemoryRepository;
6+
7+
return [
8+
9+
/*
10+
|--------------------------------------------------------------------------
11+
| Default MQTT Connection
12+
|--------------------------------------------------------------------------
13+
|
14+
| This setting defines the default MQTT connection returned when requesting
15+
| a connection without name from the facade.
16+
|
17+
*/
18+
19+
'default_connection' => 'default',
20+
21+
/*
22+
|--------------------------------------------------------------------------
23+
| MQTT Connections
24+
|--------------------------------------------------------------------------
25+
|
26+
| These are the MQTT connections used by the application. You can also open
27+
| an individual connection from the application itself, but all connections
28+
| defined here can be accessed via name conveniently.
29+
|
30+
*/
31+
32+
'connections' => [
33+
'default' => [
34+
'host' => env('MQTT_HOST'),
35+
'port' => env('MQTT_PORT', 1883),
36+
'username' => env('MQTT_USERNAME'),
37+
'password' => env('MQTT_PASSWORD'),
38+
'client_id' => env('MQTT_CLIENT_ID'),
39+
'cafile' => env('MQTT_CAFILE'),
40+
'clean_session' => env('MQTT_CLEAN_SESSION', true),
41+
'logging_enabled' => env('MQTT_LOGGING', true),
42+
'repository' => MemoryRepository::class,
43+
'settings' => [
44+
'quality_of_service' => env('MQTT_QUALITY_OF_SERVICE', 0),
45+
'block_socket' => env('MQTT_BLOCK_SOCKET', false),
46+
'keep_alive' => env('MQTT_KEEP_ALIVE', 10),
47+
'socket_timeout' => env('MQTT_TIMEOUT', 5),
48+
'resend_timeout' => env('MQTT_RESEND_TIMEOUT', 10),
49+
'retain' => env('MQTT_RETAIN', false),
50+
'last_will_topic' => env('MQTT_WILL_TOPIC'),
51+
'last_will_message' => env('MQTT_WILL_MESSAGE'),
52+
],
53+
],
54+
],
55+
56+
];

src/ConnectionManager.php

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMqtt\Client;
6+
7+
use Illuminate\Contracts\Container\BindingResolutionException;
8+
use Illuminate\Contracts\Foundation\Application;
9+
use PhpMqtt\Client\Contracts\Repository;
10+
use PhpMqtt\Client\Exceptions\ConnectingToBrokerFailedException;
11+
use PhpMqtt\Client\Exceptions\ConnectionNotAvailableException;
12+
use PhpMqtt\Client\Exceptions\DataTransferException;
13+
14+
/**
15+
* Manages the MQTT connections of the application.
16+
*
17+
* @package PhpMqtt\Client
18+
*/
19+
class ConnectionManager
20+
{
21+
/** @var Application */
22+
protected $application;
23+
24+
/** @var array */
25+
protected $config;
26+
27+
/** @var string */
28+
protected $defaultConnection;
29+
30+
/** @var MQTTClient[] */
31+
protected $connections = [];
32+
33+
/**
34+
* ConnectionManager constructor.
35+
*
36+
* @param Application $application
37+
* @param array $config
38+
*/
39+
public function __construct(Application $application, array $config)
40+
{
41+
$this->application = $application;
42+
$this->config = $config;
43+
$this->defaultConnection = array_get($config, 'default_connection', 'default');
44+
}
45+
46+
/**
47+
* Gets the connection with the specified name.
48+
*
49+
* @param string|null $name
50+
* @return MQTTClient
51+
* @throws BindingResolutionException
52+
* @throws ConnectingToBrokerFailedException
53+
* @throws ConnectionNotAvailableException
54+
*/
55+
public function connection(string $name = null): MQTTClient
56+
{
57+
if ($name === null) {
58+
$name = $this->defaultConnection;
59+
}
60+
61+
if (!array_key_exists($name, $this->connections)) {
62+
$this->connections[$name] = $this->createConnection($name);
63+
}
64+
65+
return $this->connections[$name];
66+
}
67+
68+
/**
69+
* Closes the given connection if opened.
70+
*
71+
* @param string|null $connection
72+
* @throws DataTransferException
73+
*/
74+
public function close(string $connection = null): void
75+
{
76+
if ($connection === null) {
77+
$connection = $this->defaultConnection;
78+
}
79+
80+
if (array_key_exists($connection, $this->connections)) {
81+
$this->connections[$connection]->close();
82+
unset($this->connections[$connection]);
83+
}
84+
}
85+
86+
/**
87+
* Publishes a message on the given connection. The QoS level will be 0
88+
* and the message will not be retained by the broker.
89+
*
90+
* @param string $topic
91+
* @param string $message
92+
* @param string|null $connection
93+
* @throws BindingResolutionException
94+
* @throws ConnectingToBrokerFailedException
95+
* @throws ConnectionNotAvailableException
96+
* @throws DataTransferException
97+
*/
98+
public function publish(string $topic, string $message, string $connection = null): void
99+
{
100+
$client = $this->connection($connection);
101+
102+
$client->publish($topic, $message);
103+
}
104+
105+
/**
106+
* Creates a new MQTT client and connects to the specified server.
107+
*
108+
* @param string $name
109+
* @return MQTTClient
110+
* @throws BindingResolutionException
111+
* @throws ConnectingToBrokerFailedException
112+
* @throws ConnectionNotAvailableException
113+
*/
114+
protected function createConnection(string $name): MQTTClient
115+
{
116+
$config = array_get($this->config, "connections.{$name}");
117+
if ($config === null) {
118+
throw new ConnectionNotAvailableException($name);
119+
}
120+
121+
$host = array_get($config, 'host');
122+
$port = array_get($config, 'port', 1883);
123+
$username = array_get($config, 'username');
124+
$password = array_get($config, 'password');
125+
$clientId = array_get($config, 'client_id');
126+
$caFile = array_get($config, 'cafile');
127+
$cleanSession = array_get($config, 'clean_session', true);
128+
$loggingEnabled = array_get($config, 'logging_enabled', true);
129+
$repository = array_get($config, 'repository', Repository::class);
130+
131+
$settings = $this->parseConnectionSettings(array_get($config, 'settings', []));
132+
$repository = $this->application->make($repository);
133+
$logger = $loggingEnabled ? $this->application->make('log') : null;
134+
135+
$client = new MQTTClient($host, $port, $clientId, $caFile, $repository, $logger);
136+
$client->connect($username, $password, $settings, $cleanSession);
137+
138+
return $client;
139+
}
140+
141+
/**
142+
* Parses the given settings and returns a populated settings object.
143+
*
144+
* @param array $settings
145+
* @return ConnectionSettings
146+
*/
147+
protected function parseConnectionSettings(array $settings): ConnectionSettings
148+
{
149+
$qos = array_get($settings, 'quality_of_service', 0);
150+
$blockSocket = array_get($settings, 'block_socket', false);
151+
$keepAlive = array_get($settings, 'keep_alive', 10);
152+
$socketTimeout = array_get($settings, 'socket_timeout', 5);
153+
$resendTimeout = array_get($settings, 'resend_timeout', 10);
154+
$retain = array_get($settings, 'retain', false);
155+
$lastWillTopic = array_get($settings, 'last_will_topic');
156+
$lastWillMessage = array_get($settings, 'last_will_message');
157+
158+
return new ConnectionSettings($qos, $retain, $blockSocket, $socketTimeout, $keepAlive, $resendTimeout, $lastWillTopic, $lastWillMessage);
159+
}
160+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMqtt\Client\Exceptions;
6+
7+
/**
8+
* Class ConnectionNotAvailableException
9+
*
10+
* @package PhpMqtt\Client\Exceptions
11+
*/
12+
class ConnectionNotAvailableException extends MQTTClientException
13+
{
14+
public function __construct(string $name)
15+
{
16+
parent::__construct(sprintf('An MQTT connection with the name [%s] could not be found.', $name));
17+
}
18+
}

src/Facades/MQTT.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpMqtt\Client\Facades;
6+
7+
use Illuminate\Support\Facades\Facade;
8+
use PhpMqtt\Client\ConnectionManager;
9+
use PhpMqtt\Client\MQTTClient;
10+
11+
/**
12+
* @method static MQTTClient connection(string $name = null)
13+
* @method static void close(string $connection = null)
14+
* @method static void publish(string $topic, string $message, string $connection = null)
15+
*
16+
* @see ConnectionManager
17+
* @package PhpMqtt\Client\Facades
18+
*/
19+
class MQTT extends Facade
20+
{
21+
/**
22+
* Get the registered name of the component.
23+
*
24+
* @return string
25+
*/
26+
protected static function getFacadeAccessor()
27+
{
28+
return ConnectionManager::class;
29+
}
30+
}

src/MqttClientServiceProvider.php

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PhpMqtt\Client;
44

5+
use Illuminate\Contracts\Foundation\Application;
56
use Illuminate\Support\ServiceProvider;
67

78
/**
@@ -11,54 +12,43 @@
1112
*/
1213
class MqttClientServiceProvider extends ServiceProvider
1314
{
14-
/**
15-
* Indicates if loading of the provider is deferred.
16-
*
17-
* @var bool
18-
*/
19-
protected $defer = false;
20-
21-
/**
22-
* Bootstrap the application events.
23-
*
24-
* @return void
25-
*/
26-
public function boot(): void
27-
{
28-
$this->handleConfigs();
29-
}
30-
3115
/**
3216
* Register the service provider.
3317
*
3418
* @return void
3519
*/
3620
public function register(): void
3721
{
38-
// Bind any implementations.
22+
$this->registerConfig();
23+
$this->registerServices();
3924
}
4025

4126
/**
42-
* Get the services provided by the provider.
27+
* Publishes and merges the configuration of the package.
4328
*
44-
* @return array
29+
* @return void
4530
*/
46-
public function provides(): array
31+
protected function registerConfig(): void
4732
{
48-
return [];
33+
$configPath = __DIR__ . '/../config/mqtt-client.php';
34+
35+
if ($this->app->runningInConsole()) {
36+
$this->publishes([$configPath => config_path('mqtt-client.php')], 'config');
37+
}
38+
39+
$this->mergeConfigFrom($configPath, 'mqtt-client');
4940
}
5041

5142
/**
52-
* Publishes and merges the configuration of the package.
43+
* Registers the services offered by this package.
5344
*
5445
* @return void
5546
*/
56-
protected function handleConfigs(): void
47+
protected function registerServices(): void
5748
{
58-
$configPath = __DIR__ . '/../config/mqtt-client.php';
59-
60-
$this->publishes([$configPath => config_path('mqtt-client.php')], 'config');
61-
62-
$this->mergeConfigFrom($configPath, 'mqtt-client');
49+
$this->app->bind(ConnectionManager::class, function (Application $app) {
50+
$config = $app->make('config')->get('mqtt-client', []);
51+
return new ConnectionManager($app, $config);
52+
});
6353
}
6454
}

0 commit comments

Comments
 (0)