Giter VIP home page Giter VIP logo

phpmqttclient's Introduction

PhPMqttClient

MQTT 3.1.1 Client with TSL support in PHP

Note that all calls are blocking until a timeout occurs. If you need some fancy async solution, you'll have to find another repo.

This implementation works with MQTT ver 3.1.1 for QOS levels 0 and 1. QOS level 2 should work, but is experimental until better tested.

Installation

The preferred way to install this extension is through composer.

Either run

php composer.phar require --prefer-dist karpy47/php-mqtt-client

or add

"karpy47/php-mqtt-client": "*"

to the require section of your composer.json.

Requirements

Should work with all recent PHP versions.

Code developed and running in production using PHP v7.0.27 (previously also PHP v5.6.27)

Basic Usage

use karpy47\PhpMqttClient\MQTTClient;

$client = new MQTTClient('mqtt-server.domain.com', 8162);
$client->setAuthentication('mqtt-server.username','mqtt-server.password');
$client->setEncryption('cacerts.pem');
$success = $client->sendConnect(12345);  // set your client ID
if ($success) {
    $client->sendSubscribe('topic1');
    $client->sendPublish('topic2', 'Message to all subscribers of this topic');
    $messages = $client->getPublishMessages();  // now read and acknowledge all messages waiting
    foreach ($messages as $message) {
        echo $message['topic'] .': '. $message['message'] . PHP_EOL;
        // Other keys in $message array: retain (boolean), duplicate (boolean), qos (0-2), packetId (2-byte integer)
    }
    $client->sendDisconnect();    
}
$client->close();

Credits

Thanks to bluerhinos/phpMQTT and McFizh/libMQTT.

Also thanks to

License

Released under the MIT License. Please see License File for more information.

phpmqttclient's People

Contributors

dpslwk avatar karpy47 avatar tobbexiv avatar trajche avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phpmqttclient's Issues

MQTT_QOS2 gets blocked at sendPublish function

https://github.com/karpy47/php-mqtt-client/blob/b5a932a54a51a37249ae9055a8d1beff4aa2d4a1/MQTTClient.php#L395

On line 395 there's a check for the MQTT_QOS. The check is true, if it's not MQTT_QOS0 or MQTT_QOS1 (if($qos!=self::MQTT_QOS0 && $qos!=self::MQTT_QOS1) return false;) this holds true for MQTT_QOS2.

I didn't create a pull request, as I currently don't have a broker to test MQTT_QOS2 against, but i noticed that on line 418, there's a check for MQTT_QOS2 so IMO, line 395 is wrong.
https://github.com/karpy47/php-mqtt-client/blob/b5a932a54a51a37249ae9055a8d1beff4aa2d4a1/MQTTClient.php#L418

One possible fix for Line 395 would be something like:
if (!in_array($qos, array(self::MQTT_QOS0, self::MQTT_QOS1, self::MQTT_QOS2))) return false;

Typo error

namespace karpy47/PhpMqttClient;

namespace karpy47/PhpMqttClient; should be namespace karpy47\PhpMqttClient;

also, I can get the last version only with "minimum-stability": "dev" in my composer.json

Thanks!
Simion

Newbie here ...

Hello!

I never used Composer before. I struggled with it, and managed to get composer.phar (showing options by running php composer.phar) inside my linux user folder, where /public_html is also in...

I installed your package. A /vendor folder appeared, etc. (but nothing inside /public_html).

I did navigate into my public_html folder and created a test.php. At top I placed a:

require_once '../vendor/autoload.php';

At first run, it did NOT give an error. As was my initial understanding, composer's autoload.php should include all installed packages so I can use their classes (including yours). but NOPE:

I proceeded to copy your demo code, changed connection info into my own mqtt server, port, user,pwd,client id, etc. and rerun the test.php file only to get the following error:

Fatal error: Uncaught Error: Class 'MQTTClient' not found in /home/<user>/domains/<subdomain>/public_html/test.php:2 Stack trace: #0 {main} thrown in /home/<user>/domains/<subdomain>/public_html/test.php on line 2

Then at top of my test.php, I changed the required once, now referencing your file, directly with:

require_once '../vendor/karpy47/php-mqtt-client/MQTTClient.php';

and now my PHP is giving the following error:

Parse error: syntax error, unexpected '/', expecting '{' in /home/<user>/domains/<subdomain>/vendor/karpy47/php-mqtt-client/MQTTClient.php on line 6

So now, I get into your code in MQTTClient.php and comment out line 6:

//namespace karpy47/php-mqtt-client;

AND FINALLY I GOT IT TO WORK!.

IN SHORT, my questions:

  1. I am using composer in the right way ??

  2. Isn't it easier to just grab your MQTTClient.php, paste it into /vendors or /includes or whatever folder and reference it ... and dump all the "composer" package installer / maintainer ?

Please any help and comments are appreciated, since I am very aware I might be doing something wrong and potentially unsecure.

Enrique

I don't understand why function sendConnect like this.MQTTClient.php:228

My ClientID is "admin-000". I think this clientID is OK. but MQTTClient.php:228 like this,

if(preg_match("/[^0-9a-zA-Z]/",$clientId)) { $this->debugMessage('ClientId can only contain characters 0-9,a-z,A-Z'); return false; }

I think this code means that: when my $clientId like "admin-000", then report an error: "'ClientId can only contain characters 0-9,a-z,A-Z'", which I did.

Maybe this one is OK. I verify that

if(!preg_match("/[^0-9a-zA-Z]/",$clientId)) { $this->debugMessage('ClientId can only contain characters 0-9,a-z,A-Z'); return false; }

isAlive not work

in the isAlive method
$this->serverAliveTime + $this->connectKeepAlive <= time()

should it be
$this->serverAliveTime + $this->connectKeepAlive >= time()?

Using getPublishMessages method problem

Hi
I have some missunderstanding of using sendSubscribe and getPublishMessages methods.
I need to recieve messages that subscribed, if they exist, and i don't need for waiting messages, if they are not still published by another program.
So i do the following:
Unsubscribing all and subscribing to 4 topics:

$client->sendUnsubscribe(array("username/#"));
$res[] = $client->sendSubscribe("username/current");
$res[] = $client->sendSubscribe("username/status");
$res[] = $client->sendSubscribe("username/temperature");
$res[] = $client->sendSubscribe("username/humidity");
In $res array i have all 4 topics with ["success"]=>bool(true) and ["qosGiven"]=>int(1)

Next trying different variants:

  1. $messages = $client->getPublishMessages() - recieve all messages, but very slow and always "MQTT: Read timeout" in debug.
  2. $messages = $client->getPublishMessages(0) - recieve only 3 messages (always all subscribed, but not last subscribed), fast and no timeout.
  3. $messages = $client->getPublishMessages(1) - recieve 4 messages fast and no timeout.

So, what is the right and fastest method in my case ?

And so on, if i skip sendUnsubscribe calling before sendSubscribe and getPublishMessages methods in first variant, then i recieve more than 4 messages with duplicates.
For example, i recieve 2 "username/current" topics, that different with ["retain"]=>bool(true) and ["retain"]=>bool(false).

If i use variant 3 and subscribe to absent topics, then also have duplicates of existing topics different with ["retain"]=>bool(true) and ["retain"]=>bool(false), even if use sendUnsubscribe, slowly and sometimes with "MQTT: Read timeout"

unnecessary delay in readBytes()

	        // Wait a while before trying to read again (in micro seconds)
	        usleep($this->socketReadDelay * 1000);

this code is unnecessary and adds long delays when receiving longer messages.

As the socket is in blocking mode, the fread() call blocks until it can read at least one byte. In case of timeout, it returns no data.

Cut message content for QoS 0

$message = substr($packet, 2); // skip packet id (2 bytes) and payload length (2 bytes)

In this line you assume that you always need to skip the packet id and payload length. However, this is not correct for QoS 0 messages according to the standard, they do not have a packet id: http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html#publish
Also, I am not sure whether there is a payload length as you skip only two characters which in ASCI are two bytes.

I tested this with mosquitto and don't know about Active MQ.

As a result, for QoS 0 messages, the payload is cut by the first two characters / bytes. For QoS 1, everything works fine.

Edit: Of course, for QoS 0 messages the packet id is also wrong as it is derived from the first two characters of the payload.

Undefined variable: receivedPacketId

$this->sendPubRel($receivedPacketId);

Hi,
when I try to send a QOS 2 message I get the error below
Notice: Undefined variable: receivedPacketId in D:\www\mqtt\vendor\karpy47\php-mqtt-client\MQTTClient.php on line 429

I don't understand the underlying of the MQTT protocol so I can not help :(

I get "OK" messages into another client if QOS is 0 or 1

sendUnsubscribe is not work

Hi.
I found sendUnsubscribe does not work on RabbmitMQ,
the return is true but still subscribe the topic.

Unable to install Package

Could not find a matching version of package karpy47/PhpMqttClient. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability (dev).

Reached EOF for stream Mqtt error

Hi i'm getting this error when i add ca file

MQTT: Opening socket to: tcp://35.165.61.173:1884 MQTT: Sending CONNECT MQTT: Reached EOF for stream MQTT: Closing socket MQTT: Connection failed! Error: 0 error

i have tested it on local server and it is working fine but when i try to connect to live server it is throwing the error above

karpy47 using symfony 3.4

Hi,
I'am confused how to use karpy47/PhpMqttClient using symfony 3.4. The installation using composer was 100% successuful, but i don't know if it works or not because echo isn't showing anything.
I just want to get data sent by the broker.
P.S.: I am using HiveMQ and nodered in the other side.

No subscriber messages received

Using mosquitto as Broker i do not get any (retained) subscriber messages using the example code.
I can get the message with the mosquitto CLI subscriber.

Namespacing

Hi,

Please update the name spacing to standards. The namespacing is causing issues because it contains - character

Requests extremely slow

Hello, all I want to do is to send a message to a topic
and receive the response who is actually stored in another topic
What I did for the moment is that : ```php
$peripheral = $request->route('peripheral');
$client = new MQTTClient('my.mqtt.domain', 1883);
$success = $client->sendConnect(uniqid());
$status = NULL;
$espStatus = NULL;
if ($success) {
$client->sendSubscribe($peripheral . '/out');
$client->sendPublish($peripheral . '/in', '$');
$messages = $client->getPublishMessages();
foreach ($messages as $message) {
$status = json_decode($message['message'], true);
}
$client->sendDisconnect();
} else {
echo 'Not able to connect to the main server, aborting...';
}

Is there any way to speed up the process?

Autmatic sync with packagist does not seem to work

As the latest version on packagist is v1.0.1 from August 2017, I use dev-master for now. However, this also does not always have the latest changes included. For example, now the dev-master version on packagist is from 2019-01-12 07:05 UTC and all changes done later are not included. Could you please check whether you GitHub webhook is working properly or set up one if you do not have one?

Thank you :)

Validation

In the function sendConnect() the following lines cause us problems as the server we are using allows different characters and a longer string length:

	    if(preg_match("/[^0-9a-zA-Z]/",$clientId)) {
	        $this->debugMessage('ClientId can only contain characters 0-9,a-z,A-Z');
	        return false;
	    }
	    if(strlen($clientId) > 23) {
	        $this->debugMessage('ClientId max length is 23 characters/numbers');
	        return false;
	    }

I suggest having this as an option or removing it altogether.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.