php-mqtt/client

Transferring data over socket failed

DancingDream opened this issue · 6 comments

hi, I have a problem. An error occurred when I pushed a new message after I subscribed to the topic circularly. The server can receive new messages.
1681715358

Please provide the code you are using.

That's only half of the code, the connect part is missing. It is also a potential issue that you are using globals and sleep in your code. Depending on the timeouts you used for the connection, the broker may simply have disconnected you.

Regarding your logic, there is an issue as well:
Calling $mqtt->subscribe(...) will only issue the subscription request, but it is not a working subscription just yet. You need to call $mqtt->loop() for it to become a valid subscription because the MQTT broker has to acknowledge it. This may need some time (commonly a few milliseconds, depending on the connection). Whether you can publish a message to yourself, depends on the broker - some MQTT brokers do not broadcast messages to the sender if they run subscriptions as well.

Is using globals and sleep an issue then? I'm also seeing the same error from time to time.

This is my code: https://github.com/Egregius/PHP-Floorplan-and-advanced-automation-for-Domoticz/blob/master/secure/pass4mqtt.php

As I've written before, globals are very dangerous and completely outdated in modern PHP. Also is actively sleeping between MQTT actions an issue because the underlying TCP connection will time out. This is nothing this library can prevent. You can maybe increase the timeouts in the ConnectionSettings, but whether that helps depends a lot on the MQTT broker and its settings as well.

wivwiv commented

I'm having the same problem. Both setKeepAliveInterval(10) and setKeepAliveInterval(60) subscriptions report an error after a certain period of time.

version: v1.8.0

result

...
countt: 129
PHP Fatal error:  Uncaught PhpMqtt\Client\Exceptions\DataTransferException: [66] Transferring data over socket failed: Reading data from the socket failed. Has it been closed? in /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php:1213
Stack trace:
#0 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php(1267): PhpMqtt\Client\MqttClient->readFromSocket(8192, true)
#1 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php(676): PhpMqtt\Client\MqttClient->readAllAvailableDataFromSocket(true)
#2 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php(649): PhpMqtt\Client\MqttClient->loopOnce(1691044071.4771, true)
#3 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/pubsub_tcp.php(60): PhpMqtt\Client\MqttClient->loop(true)
#4 {main}
  thrown in /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php on line 1213

Fatal error: Uncaught PhpMqtt\Client\Exceptions\DataTransferException: [66] Transferring data over socket failed: Reading data from the socket failed. Has it been closed? in /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php:1213
Stack trace:
#0 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php(1267): PhpMqtt\Client\MqttClient->readFromSocket(8192, true)
#1 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php(676): PhpMqtt\Client\MqttClient->readAllAvailableDataFromSocket(true)
#2 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php(649): PhpMqtt\Client\MqttClient->loopOnce(1691044071.4771, true)
#3 /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/pubsub_tcp.php(60): PhpMqtt\Client\MqttClient->loop(true)
#4 {main}
  thrown in /Users/emqx/workspace/MQTT-Client-Examples/mqtt-client-PHP/vendor/php-mqtt/client/src/MqttClient.php on line 1213

code

<?php

require('vendor/autoload.php');

use \PhpMqtt\Client\MqttClient;
use \PhpMqtt\Client\ConnectionSettings;

$server   = 'broker.emqx.io';
$port     = 1883;
$clientId = rand(5, 15);
$username = 'emqx_user';
$password = 'public';
$clean_session = false;
$mqtt_version = MqttClient::MQTT_3_1_1;

$connectionSettings  = (new ConnectionSettings)
  ->setUsername($username)
  ->setPassword($password)
  ->setKeepAliveInterval(10)
  // Last Will 设置
  ->setLastWillTopic('emqx/test/last-will')
  ->setLastWillMessage('client disconnect')
  ->setLastWillQualityOfService(1);


$mqtt = new MqttClient($server, $port, $clientId, $mqtt_version);

$mqtt->connect($connectionSettings, $clean_session);
printf("client connected\n");

$countt = 0;

$mqtt->subscribe('emqx/test', function ($topic, $message) {
    // printf("Received message on topic [%s]: %s\n", $topic, $message);
    global $countt;
    $countt = $countt + 1;
    printf("countt: %s\n", $countt);
}, 0);

// for ($i = 0; $i< 10; $i++) {
//   $payload = array(
//     'protocol' => 'tcp',
//     'date' => date('Y-m-d H:i:s'),
//     'url' => 'https://github.com/emqx/MQTT-Client-Examples'
//   );
//   $mqtt->publish(
//     // topic
//     'emqx/test',
//     // payload
//     json_encode($payload),
//     // qos
//     0,
//     // retain
//     true
//   );
//   printf("msg $i send\n");
//   sleep(1);
// }

$mqtt->loop(true);