Skip to content

[WIP] Add new RedisRepository #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 59 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
6f9ab8b
Add more documentation
Namoshek Jul 13, 2020
03f6657
Use QoS constant in ConnectionSettings
Namoshek Jul 13, 2020
40b3bc4
Add isConnected() method to MQTTClient (contract)
Namoshek Jul 13, 2020
76354fc
Ensure client is connected before performing actions
Namoshek Jul 13, 2020
841812f
Use QoS constants in favour of integers
Namoshek Jul 13, 2020
7026aea
Document hooks in MQTTClient contract
Namoshek Jul 15, 2020
8587462
Improve PhpDoc of the interrupt() method
Namoshek Jul 15, 2020
b6a0ee9
Remove unused shift($buffer, $limit) method
Namoshek Jul 15, 2020
64bff72
Extract pure functions into traits
Namoshek Jul 15, 2020
400b906
Replace local message id with a manager implementation
Namoshek Jul 15, 2020
dddd646
Add missing connection handshake errors of v3.1
Namoshek Jul 15, 2020
47c55c7
Merge MessageIdManager into Repository
Namoshek Jul 21, 2020
37659b0
Refactor ConnectionSettings
Namoshek Jul 21, 2020
a1064f0
Avoid passing null for cafile/capath to context
Namoshek Jul 21, 2020
54da907
Improve logging
Namoshek Jul 22, 2020
29e9807
Add and use log helpers
Namoshek Jul 22, 2020
2508b20
Wrap calling registered callbacks in try-catch
Namoshek Jul 22, 2020
8102ef1
Rename MQTTClient to MqttClient
Namoshek Jul 24, 2020
0f63e08
Always create a socket context
Namoshek Jul 24, 2020
54db310
Rename remaining occurences of MQTTClient* to MqttClient* (#18)
thg2k Jul 25, 2020
7ce99f4
Refactor MqttClient protocol logic into MessageProcessor implementati…
Namoshek Jul 26, 2020
e06349f
Use string to represent protocol version
Namoshek Jul 28, 2020
77d8dd0
Make ConnectionSettings immutable
Namoshek Jul 28, 2020
7340eaf
Fix double use of $
Namoshek Jul 28, 2020
2c8b170
Restructure and rename connection settings
Namoshek Jul 28, 2020
96071aa
Restructure ConnectionSetting properties again
Namoshek Jul 28, 2020
7db80ed
Update README.md
Namoshek Jul 28, 2020
e936d65
Remove the option use blocking mode for the socket
Namoshek Jul 28, 2020
5f7a3c1
Add connection settings validation
Namoshek Jul 28, 2020
6fe1fae
Fix phpcs
Namoshek Jul 28, 2020
bbbe7d8
Add constructors to exceptions
Namoshek Jul 29, 2020
1eca58b
Implement TLS updates of master
Namoshek Jul 29, 2020
184dea4
Validate subscription before calling unsubscribe()
Namoshek Jul 29, 2020
cc8c896
Remove obsolete TODO
Namoshek Jul 29, 2020
18df96e
Add client certificate support for TLS
Namoshek Jul 29, 2020
96ce1ce
Fix issue when not passing any connection settings
Namoshek Aug 1, 2020
8dbfc50
Make stream non-blocking
Namoshek Aug 1, 2020
9b4b529
Add safety break when decoding message length
Namoshek Aug 1, 2020
3e663ab
Fix message length encoding
Namoshek Aug 1, 2020
1b3d6ef
Add composer scripts for tests
Namoshek Aug 1, 2020
3fa1cf2
Add getters for received and sent bytes
Namoshek Aug 2, 2020
e5c3d29
Add unit test for buildConnectMessage()
Namoshek Aug 2, 2020
6d666ab
Add unit test for buildSubscribeMessage()
Namoshek Aug 2, 2020
9be340c
Add unit test for buildPingMessage()
Namoshek Aug 2, 2020
30d76c4
Add remaining unit tests for message processor
Namoshek Aug 3, 2020
1a7aadf
Implement draft of RedisRepository
Namoshek Aug 9, 2020
c169c24
Subscribers of lower QoS receive higher QoS too
Namoshek Aug 12, 2020
bc287db
Run test and code style pipeline on push and PR
Namoshek Aug 19, 2020
50004bd
Fix code style issues
Namoshek Aug 19, 2020
c9984c5
Inline 'addNew(...)' methods to MqttClient to reduce Repository inter…
thg2k Aug 19, 2020
38c1a38
Add missing PUBREL in response to PUBREC
Namoshek Aug 19, 2020
6a237c1
Use camelCase for logging context
Namoshek Aug 19, 2020
1326427
Merge branch 'refactoring' of github.com:php-mqtt/client into refacto…
Namoshek Aug 19, 2020
746203a
Removed 'BaseRepository' class as it's covered by the 'Repository' in…
thg2k Aug 19, 2020
19dcbfd
Fix message format of PUBREL since we expect ack
Namoshek Aug 19, 2020
319cbd8
Refactory repository interface with single pending message and subscr…
thg2k Aug 23, 2020
18d366e
Add RedisRepository
Namoshek Sep 1, 2020
69a0386
Fix minor issues with MemoryRepository
Namoshek Sep 1, 2020
566026e
Pass message id to Redis as string
Namoshek Oct 24, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Tests

on: [push]
on: [push, pull_request]

jobs:
test-all:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/verify-code-style.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: 'PR: Verify Code Style'
name: 'Verify Code Style'

on: pull_request
on: [push, pull_request]

jobs:
phpcs:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.idea/
/vendor/
.phpunit.result.cache
1 change: 0 additions & 1 deletion .phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
<rule ref="Zend.Files.ClosingTag"/>

<file>src</file>
<file>tests</file>

<arg name="colors"/>
<arg value="sp"/>
Expand Down
81 changes: 75 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
# php-mqtt/client

[![Latest Stable Version](https://poser.pugx.org/php-mqtt/client/v)](//packagist.org/packages/php-mqtt/client) [![Total Downloads](https://poser.pugx.org/php-mqtt/client/downloads)](//packagist.org/packages/php-mqtt/client) [![License](https://poser.pugx.org/php-mqtt/client/license)](//packagist.org/packages/php-mqtt/client)
[![Latest Stable Version](https://poser.pugx.org/php-mqtt/client/v)](//packagist.org/packages/php-mqtt/client)
[![Total Downloads](https://poser.pugx.org/php-mqtt/client/downloads)](//packagist.org/packages/php-mqtt/client)
[![License](https://poser.pugx.org/php-mqtt/client/license)](//packagist.org/packages/php-mqtt/client)

[`php-mqtt/client`](https://packagist.org/packages/php-mqtt/client) was created by, and is maintained by [Namoshek](https://github.com/namoshek).
[`php-mqtt/client`](https://packagist.org/packages/php-mqtt/client) was created by, and is maintained
by [Namoshek](https://github.com/namoshek).
It allows you to connect to an MQTT broker where you can publish messages and subscribe to topics.
The implementation supports all QoS levels ([with limitations](#limitations)).
The current implementation supports all QoS levels ([with limitations](#limitations)).

## Installation

Expand All @@ -23,7 +26,7 @@ A very basic publish example requires only three steps: connect, publish and clo
```php
$clientId = 'test-publisher';

$mqtt = new MQTTClient($server, $port, $clientId);
$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
$mqtt->connect();
$mqtt->publish('php-mqtt/client/test', 'Hello World!', 0);
$mqtt->close();
Expand All @@ -40,7 +43,7 @@ Subscribing is a little more complex than publishing as it requires to run an ev
```php
$clientId = 'test-subscriber';

$mqtt = new MQTTClient($server, $port, $clientId);
$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
$mqtt->connect();
$mqtt->subscribe('php-mqtt/client/test', function ($topic, $message) {
echo sprintf("Received message on topic [%s]: %s\n", $topic, $message);
Expand All @@ -56,7 +59,7 @@ pcntl_async_signals(true);

$clientId = 'test-subscriber';

$mqtt = new MQTTClient($server, $port, $clientId);
$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
pcntl_signal(SIGINT, function (int $signal, $info) use ($mqtt) {
$mqtt->interrupt();
});
Expand All @@ -68,6 +71,72 @@ $mqtt->loop(true);
$mqtt->close();
```

### Client Settings

As shown in the examples above, the `MqttClient` takes the server, port and client id as first, second and third parameter.
As fourth parameter, the protocol level can be passed. Currently supported is MQTT v3.1,
available as constant `MqttClient::MQTT_3_1`.
A fifth parameter allows passing a repository (currently, only a `MemoryRepository` is available by default).
Lastly, a logger can be passed as sixth parameter. If none is given, a null logger is used instead.

Example:
```php
$mqtt = new \PhpMqtt\Client\MQTTClient(
$server,
$port,
$clientId,
MqttClient::MQTT_3_1,
new \PhpMqtt\Client\Repositories\MemoryRepository(),
new Logger()
);
```

The `Logger` must implement the `Psr\Log\LoggerInterface`.

### Connection Settings

The `connect()` method of the `MQTTClient` takes two optional parameters:
1. A `ConnectionSettings` instance
2. A `boolean` flag indicating whether a clean session should be requested (a random client id does this implicitly)

Example:
```php
$mqtt = new \PhpMqtt\Client\MQTTClient($server, $port, $clientId);

$connectionSettings = new \PhpMqtt\Client\ConnectionSettings();
$mqtt->connect($connectionSettings, true);
```

The `ConnectionSettings` class provides a few settings through a fluent interface. The type itself is immutable,
and a new `ConnectionSettings` instance will be created for each added option.
This also prevents changes to the connection settings after a connection has been established.

The following is a complete list of options with their respective default:
```php
$connectionSettings = (new \PhpMqtt\Client\ConnectionSettings())

// The QoS level
->setUsername(null)
->setPassword(null)
->setConnectTimeout(60)
->setSocketTimeout(5)
->setKeepAliveInterval(10)
->setResendTimeout(10)
->setLastWillTopic(null)
->setLastWillMessage(null)
->setLastWillQualityOfService(0)
->setRetainLastWill(false)
->setUseTls(false)
->setTlsVerifyPeer(true)
->setTlsVerifyPeerName(true)
->setTlsSelfSignedAllowed(false)
->setTlsCertificateAuthorityFile(null)
->setTlsCertificateAuthorityPath(null)
->setTlsClientCertificateFile(null)
->setTlsClientCertificateKeyFile(null)
->setTlsClientCertificatePassphrase(null);
```

## Features

- MQTT Versions
Expand Down
23 changes: 20 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,33 @@
"PhpMqtt\\Client\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"require": {
"php": "^7.2",
"psr/log": "^1.1"
"psr/log": "^1.1",
"myclabs/php-enum": "^1.7",
"opis/closure": "^3.5"
},
"require-dev": {
"phpunit/phpunit": "^8.0",
"squizlabs/php_codesniffer": "^3.5"
},
"suggest": {
"ext-redis": "Required for the RedisRepository"
},
"scripts": {
"test:cs": "vendor/bin/phpcs src tests",
"fix:cs": "vendor/bin/phpcbf src tests"
"fix:cs": "vendor/bin/phpcbf",
"test": [
"@test:cs",
"@test:unit",
"@test:feature"
],
"test:cs": "vendor/bin/phpcs",
"test:feature": "vendor/bin/phpunit --testsuite Feature",
"test:unit": "vendor/bin/phpunit --testsuite Unit"
}
}
121 changes: 114 additions & 7 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions src/Concerns/GeneratesRandomClientIds.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace PhpMqtt\Client\Concerns;

/**
* Provides common methods used to generate random client ids.
*
* @package PhpMqtt\Client\Concerns
*/
trait GeneratesRandomClientIds
{
/**
* Generates a random client id in the form of an md5 hash.
*
* @return string
*/
protected function generateRandomClientId(): string
{
return substr(md5(uniqid((string) mt_rand(), true)), 0, 20);
}
}
Loading