Search code examples
laravelmqttmosquittophpmqtt

PHP-MQTT publisher crashes subscriber


I have the following docker containerized Mosquitto:

ecosystem:
    image: eclipse-mosquitto:latest
    ports:
      - '1883:1883'
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data
      - ./mosquitto/log:/mosquitto/log
    networks: [ default, odinn_network ]
    restart: unless-stopped

mosquitto.conf contains just few lines:

allow_anonymous true
listener 1883

Then I try to get subscription by PHP-MQTT. To keep it simple I use tinker to interpret PHP code. Subsriber code is:

use PhpMqtt\Client\MqttClient;
$mqtt = new MqttClient('localhost', 1883, 'test');
$mqtt->connect();
$mqtt->subscribe('events/#', function ($topic, $message) { fwrite(STDERR, sprintf("topic = %s / message = %s\n", $topic, $message)); });
$mqtt->loop(true);

Step 1 - try to use CLI publisher mosquitto_pub - mosquitto_pub -h localhost -p 1883 -t events/123456 -m test. Susbriber works fine and topic = events/123456 / message = test2 printed out in subscriber' tinker - that's right.

Step 2 - try to publish by PHP-MQTT:

use PhpMqtt\Client\MqttClient;
$mqtt = new MqttClient('localhost', 1883, 'test');
$mqtt->connect();
$mqtt->publish('events/123456', 'test');

Fatal - subscription loop crashes with the following message - PhpMqtt\Client\Exceptions\DataTransferException [65] Transferring data over socket failed: Sending data over the socket failed. Has it been closed?

Which socket? What's happened?


Solution

  • MQTT Client IDs must be globally unique across all clients connected to the broker.

    You are using test for all your PHP clients, so the second one to connect will kick the first off when it starts in line with the MQTT spec