13 Commits

Author SHA1 Message Date
0669643386 Update minimum php-mqtt/client version (#39)
Versions before 1.3.0 don't have setReconnectAutomatically
2023-04-05 18:41:07 +02:00
936ce0549d GHA: Run tests against PHP 8.2 (#37) 2023-02-14 20:50:15 +01:00
c42ec1d6ff Laravel 10.x Compatibility (#35)
* Bump dependencies for Laravel 10

* Update version constraints in composer.json

---------

Co-authored-by: Marvin Mall <marvin-mall@msn.com>
2023-02-14 20:41:59 +01:00
d2a2a839e4 Fix: PR target event allows external builds (#32) 2022-11-22 22:32:07 +01:00
fe0cb883e7 Add auto reconnect support (#31)
* Update mqtt-client.php

* Update ConnectionManager.php

* Update mqtt-client.php

* Update mqtt-client.php

* Update mqtt-client.php

* Update ConnectionManager.php

* Update mqtt-client.php

* Add and normalize auto-reconnect settings

* Add .gitkeep

* Remove .gitkeep

Co-authored-by: Marvin Mall <marvin-mall@msn.com>
2022-11-22 22:26:38 +01:00
136ce2cb75 Bump actions/checkout from 2 to 3 (#24)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-04-10 15:50:12 +02:00
c398d5ec07 Add Dependabot and improve build pipeline (#23)
* Add dependabot config

* Update actions/cache and simplify variable usage in build
2022-04-10 15:45:17 +02:00
d237909b6d Feature laravel 9 (#22)
* Support Laravel 9

* Build and test using PHP 8.1
2022-02-10 19:22:40 +01:00
7dfaac06e4 Fix: Recreate disconnected connections when being retrieved (#19) 2022-01-08 14:23:13 +01:00
9e69fb1e45 Use php-mqtt/client:^1.0 2021-01-10 19:50:26 +01:00
895dc58a20 Add SonarQube badges 2021-01-05 20:28:52 +01:00
fefbd82c59 Add code style enforcement and GitHub Actions workflow for tests (#3)
* Add PHP_CodeSniffer and fix code style

* Add test pipeline and SonarQube analysis

* Fix job name of workflow
2021-01-05 20:25:53 +01:00
082f2f25b1 Cast config values for strict type matching (#2) 2021-01-05 20:10:57 +01:00
9 changed files with 281 additions and 55 deletions

23
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,23 @@
version: 2
updates:
- package-ecosystem: "composer"
directory: "/"
allow:
- dependency-type: "development"
schedule:
interval: "daily"
time: "05:00"
timezone: "Europe/Vienna"
labels:
- "composer dependencies"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "05:00"
timezone: "Europe/Vienna"
labels:
- "github actions"

64
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,64 @@
name: Tests
on:
push:
branches:
- master
pull_request_target:
types: [opened, synchronize, reopened]
jobs:
test-all:
name: Test PHP ${{ matrix.php-version }}
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['7.4', '8.0', '8.1', '8.2']
include:
- php-version: '8.2'
run-sonarqube-analysis: true
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup PHP ${{ matrix.php-version }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: phpunit:9.5.0
coverage: pcov
- name: Setup problem matchers for PHP
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
- name: Setup problem matchers for PHPUnit
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache Composer dependencies
uses: actions/cache@v3
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install composer dependencies
run: composer install --prefer-dist --ignore-platform-reqs
- name: Run tests
run: composer test
- name: Run SonarQube analysis
uses: sonarsource/sonarcloud-github-action@master
if: matrix.run-sonarqube-analysis
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONARCLOUD_TOKEN }}

88
.phpcs.xml Normal file
View File

@ -0,0 +1,88 @@
<?xml version="1.0"?>
<ruleset name="php-mqtt Code Style Standard">
<description>php-mqtt Code Style Standard</description>
<rule ref="PSR1"/>
<rule ref="PSR2">
<exclude name="PSR2.Methods.MethodDeclaration.AbstractAfterVisibility"/>
<exclude name="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseParenthesis"/>
</rule>
<rule ref="Generic.Arrays.ArrayIndent">
<exclude name="Generic.Arrays.ArrayIndent.CloseBraceNotNewLine"/>
</rule>
<rule ref="Generic.Classes.DuplicateClassName"/>
<rule ref="Generic.CodeAnalysis.EmptyStatement">
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch"/>
</rule>
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
<rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
<rule ref="Generic.Commenting.Todo">
<exclude-pattern>src/*</exclude-pattern>
</rule>
<rule ref="Generic.ControlStructures.InlineControlStructure"/>
<rule ref="Generic.Files.ByteOrderMark"/>
<rule ref="Generic.Files.LineEndings"/>
<rule ref="Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="150"/>
<property name="absoluteLineLimit" value="0"/>
</properties>
</rule>
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
<rule ref="Generic.Formatting.MultipleStatementAlignment"/>
<rule ref="Generic.Formatting.SpaceAfterCast"/>
<rule ref="Generic.Functions.CallTimePassByReference"/>
<rule ref="Generic.Functions.FunctionCallArgumentSpacing"/>
<rule ref="Generic.Functions.OpeningFunctionBraceBsdAllman"/>
<rule ref="Generic.Metrics.CyclomaticComplexity">
<properties>
<property name="complexity" value="50"/>
<property name="absoluteComplexity" value="100"/>
</properties>
</rule>
<rule ref="Generic.Metrics.NestingLevel">
<properties>
<property name="nestingLevel" value="10"/>
<property name="absoluteNestingLevel" value="30"/>
</properties>
</rule>
<rule ref="Generic.NamingConventions.ConstructorName"/>
<rule ref="Generic.PHP.LowerCaseConstant"/>
<rule ref="Generic.PHP.DeprecatedFunctions"/>
<rule ref="Generic.PHP.DisallowShortOpenTag"/>
<rule ref="Generic.PHP.ForbiddenFunctions"/>
<rule ref="Generic.WhiteSpace.DisallowTabIndent"/>
<rule ref="Generic.WhiteSpace.ScopeIndent">
<properties>
<property name="indent" value="4"/>
</properties>
</rule>
<rule ref="MySource.PHP.EvalObjectFactory"/>
<rule ref="PEAR.Commenting.ClassComment">
<exclude name="PEAR.Commenting.ClassComment.MissingAuthorTag"/>
<exclude name="PEAR.Commenting.ClassComment.MissingCategoryTag"/>
<exclude name="PEAR.Commenting.ClassComment.MissingLicenseTag"/>
<exclude name="PEAR.Commenting.ClassComment.MissingLinkTag"/>
</rule>
<rule ref="PEAR.Commenting.ClassComment.Missing"/>
<rule ref="PEAR.Commenting.ClassComment.MissingPackageTag"/>
<rule ref="PEAR.Commenting.InlineComment"/>
<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace"/>
<rule ref="PSR2.Methods.FunctionClosingBrace.SpacingBeforeClose"/>
<rule ref="Squiz.Arrays.ArrayDeclaration.NoCommaAfterLast"/>
<rule ref="Squiz.Functions.MultiLineFunctionDeclaration.NewlineBeforeOpenBrace">
<exclude-pattern>src/*</exclude-pattern>
</rule>
<rule ref="Zend.Files.ClosingTag"/>
<file>src</file>
<arg name="colors"/>
<arg value="sp"/>
<ini name="memory_limit" value="128M"/>
</ruleset>

View File

@ -2,6 +2,12 @@
[![Latest Stable Version](https://poser.pugx.org/php-mqtt/laravel-client/v)](https://packagist.org/packages/php-mqtt/laravel-client)
[![Total Downloads](https://poser.pugx.org/php-mqtt/laravel-client/downloads)](https://packagist.org/packages/php-mqtt/laravel-client)
[![Tests](https://github.com/php-mqtt/laravel-client/workflows/Tests/badge.svg)](https://github.com/php-mqtt/laravel-client/actions?query=workflow%3ATests)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=php-mqtt_laravel-client&metric=alert_status)](https://sonarcloud.io/dashboard?id=php-mqtt_laravel-client)
[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=php-mqtt_laravel-client&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=php-mqtt_laravel-client)
[![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=php-mqtt_laravel-client&metric=reliability_rating)](https://sonarcloud.io/dashboard?id=php-mqtt_laravel-client)
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=php-mqtt_laravel-client&metric=security_rating)](https://sonarcloud.io/dashboard?id=php-mqtt_laravel-client)
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=php-mqtt_laravel-client&metric=vulnerabilities)](https://sonarcloud.io/dashboard?id=php-mqtt_laravel-client)
[![License](https://poser.pugx.org/php-mqtt/laravel-client/license)](https://packagist.org/packages/php-mqtt/laravel-client)
`php-mqtt/laravel-client` was created by, and is maintained by [Marvin Mall](https://github.com/namoshek).

View File

@ -1,42 +1,52 @@
{
"name": "php-mqtt/laravel-client",
"description": "A wrapper for the php-mqtt/client library for Laravel.",
"type": "library",
"keywords": [
"mqtt",
"client",
"publish",
"subscribe",
"laravel"
],
"homepage": "https://github.com/php-mqtt/laravel-client",
"license": "MIT",
"authors": [
{
"name": "Marvin Mall",
"email": "marvin-mall@msn.com",
"role": "developer"
"name": "php-mqtt/laravel-client",
"description": "A wrapper for the php-mqtt/client library for Laravel.",
"type": "library",
"keywords": [
"mqtt",
"client",
"publish",
"subscribe",
"laravel"
],
"homepage": "https://github.com/php-mqtt/laravel-client",
"license": "MIT",
"authors": [
{
"name": "Marvin Mall",
"email": "marvin-mall@msn.com",
"role": "developer"
}
],
"require": {
"php": "^7.4|^8.0",
"illuminate/config": "^7.0|^8.0|^9.0|^10.0",
"illuminate/support": "^7.0|^8.0|^9.0|^10.0",
"php-mqtt/client": "^1.3.0"
},
"require-dev": {
"squizlabs/php_codesniffer": "^3.5"
},
"autoload": {
"psr-4": {
"PhpMqtt\\Client\\": "src"
}
},
"extra": {
"laravel": {
"providers": [
"PhpMqtt\\Client\\MqttClientServiceProvider"
],
"aliases": {
"MQTT": "PhpMqtt\\Client\\Facades\\MQTT"
}
}
},
"scripts": {
"fix:cs": "vendor/bin/phpcbf",
"test": [
"@test:cs"
],
"test:cs": "vendor/bin/phpcs"
}
],
"require": {
"php": "^7.4|^8.0",
"illuminate/config": "~7.0|~8.0",
"illuminate/support": "~7.0|~8.0",
"php-mqtt/client": "v1.0.0-rc1"
},
"autoload": {
"psr-4": {
"PhpMqtt\\Client\\": "src"
}
},
"extra": {
"laravel": {
"providers": [
"PhpMqtt\\Client\\MqttClientServiceProvider"
],
"aliases": {
"MQTT": "PhpMqtt\\Client\\Facades\\MQTT"
}
}
}
}

View File

@ -101,6 +101,14 @@ return [
// 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),
],
],
],

18
sonar-project.properties Normal file
View File

@ -0,0 +1,18 @@
sonar.organization=php-mqtt
sonar.projectKey=php-mqtt_laravel-client
# Paths are relative to the sonar-project.properties file.
sonar.sources=src
#sonar.tests=tests
# Test report and code coverage related settings.
#sonar.php.tests.reportPath=phpunit.report-junit.xml
#sonar.php.coverage.reportPaths=phpunit.coverage-clover.xml
# Encoding of the source code. Default is default system encoding.
sonar.sourceEncoding=UTF-8
# Links for sonarcloud.io page.
sonar.links.ci=https://github.com/php-mqtt/laravel-client/actions
sonar.links.scm=https://github.com/php-mqtt/laravel-client
sonar.links.issue=https://github.com/php-mqtt/laravel-client/issues

View File

@ -60,6 +60,12 @@ class ConnectionManager
$name = $this->defaultConnection;
}
// Remove the connection if it is in a disconnected state.
// Doing this instead of simply reconnecting ensures the caller will get a fresh connection.
if (array_key_exists($name, $this->connections) && !$this->connections[$name]->isConnected()) {
unset($this->connections[$name]);
}
if (!array_key_exists($name, $this->connections)) {
$this->connections[$name] = $this->createConnection($name);
}
@ -126,13 +132,13 @@ class ConnectionManager
throw new ConnectionNotAvailableException($name);
}
$host = Arr::get($config, 'host');
$port = Arr::get($config, 'port', 1883);
$host = (string) Arr::get($config, 'host');
$port = (int) Arr::get($config, 'port', 1883);
$clientId = Arr::get($config, 'client_id');
$protocol = Arr::get($config, 'protocol', MqttClient::MQTT_3_1);
$cleanSession = Arr::get($config, 'use_clean_session', true);
$protocol = (string) Arr::get($config, 'protocol', MqttClient::MQTT_3_1);
$cleanSession = (bool) Arr::get($config, 'use_clean_session', true);
$repository = Arr::get($config, 'repository', Repository::class);
$loggingEnabled = Arr::get($config, 'enable_logging', true);
$loggingEnabled = (bool) Arr::get($config, 'enable_logging', true);
$settings = $this->buildConnectionSettings(Arr::get($config, 'connection_settings', []));
$repository = $this->application->make($repository);
@ -153,16 +159,16 @@ class ConnectionManager
protected function buildConnectionSettings(array $config): ConnectionSettings
{
return (new ConnectionSettings)
->setConnectTimeout(Arr::get($config, 'connect_timeout', 60))
->setSocketTimeout(Arr::get($config, 'socket_timeout', 5))
->setResendTimeout(Arr::get($config, 'resend_timeout', 10))
->setKeepAliveInterval(Arr::get($config, 'keep_alive_interval', 10))
->setConnectTimeout((int) Arr::get($config, 'connect_timeout', 60))
->setSocketTimeout((int) Arr::get($config, 'socket_timeout', 5))
->setResendTimeout((int) Arr::get($config, 'resend_timeout', 10))
->setKeepAliveInterval((int) Arr::get($config, 'keep_alive_interval', 10))
->setUsername(Arr::get($config, 'auth.username'))
->setPassword(Arr::get($config, 'auth.password'))
->setUseTls(Arr::get($config, 'tls.enabled', false))
->setTlsSelfSignedAllowed(Arr::get($config, 'tls.allow_self_signed_certificate', false))
->setTlsVerifyPeer(Arr::get($config, 'tls.verify_peer', true))
->setTlsVerifyPeerName(Arr::get($config, 'tls.verify_peer_name', true))
->setUseTls((bool) Arr::get($config, 'tls.enabled', false))
->setTlsSelfSignedAllowed((bool) Arr::get($config, 'tls.allow_self_signed_certificate', false))
->setTlsVerifyPeer((bool) Arr::get($config, 'tls.verify_peer', true))
->setTlsVerifyPeerName((bool) Arr::get($config, 'tls.verify_peer_name', true))
->setTlsCertificateAuthorityFile(Arr::get($config, 'tls.ca_file'))
->setTlsCertificateAuthorityPath(Arr::get($config, 'tls.ca_path'))
->setTlsClientCertificateFile(Arr::get($config, 'tls.client_certificate_file'))
@ -170,7 +176,10 @@ class ConnectionManager
->setTlsClientCertificateKeyPassphrase(Arr::get($config, 'tls.client_certificate_key_passphrase'))
->setLastWillTopic(Arr::get($config, 'last_will.topic'))
->setLastWillMessage(Arr::get($config, 'last_will.message'))
->setLastWillQualityOfService(Arr::get($config, 'last_will.quality_of_service', MqttClient::QOS_AT_MOST_ONCE))
->setRetainLastWill(Arr::get($config, 'last_will.retain', false));
->setLastWillQualityOfService((int) Arr::get($config, 'last_will.quality_of_service', MqttClient::QOS_AT_MOST_ONCE))
->setRetainLastWill((bool) Arr::get($config, 'last_will.retain', false))
->setReconnectAutomatically((bool) Arr::get($config, 'auto_reconnect.enabled', false))
->setMaxReconnectAttempts((int) Arr::get($config, 'auto_reconnect.max_reconnect_attempts', 3))
->setDelayBetweenReconnectAttempts((int) Arr::get($config, 'auto_reconnect.delay_between_reconnect_attempts', 0));
}
}

View File

@ -13,8 +13,8 @@ use PhpMqtt\Client\Contracts\MqttClient;
* @method static void disconnect(string $connection = null)
* @method static void publish(string $topic, string $message, bool $retain = false, string $connection = null)
*
* @see ConnectionManager
* @package PhpMqtt\Client\Facades
* @see ConnectionManager
*/
class MQTT extends Facade
{