PHP MQTT Server

A Swoole MQTT Server is a TCP server with MQTT protocol enabled.

MQTT protocol is supported by both Swoole Server and Client. You can enable the MQTT protocol by setting open_mqtt_protocol to be TRUE at the server.

The MQTT packages will be received at the receive callback function. Then you can parse the MQTT package based on your requirement.

You can use the methods of Swoole\Server within a MQTT Server.

MQTT Server Example

<?php
function decodeValue($data) {
    return 256 * ord($data[0]) + ord($data[1]);
}

function decodeString($data) {
    $length = decodeValue($data);
    return substr($data, 2, $length);
}

function mqttGetHeader($data) {
    $byte = ord($data[0]);

    $header['type'] = ($byte & 0xF0) >> 4;
    $header['dup'] = ($byte & 0x08) >> 3;
    $header['qos'] = ($byte & 0x06) >> 1;
    $header['retain'] = $byte & 0x01;

    return $header;
}

function eventConnect($header, $data) {
    $connect_info['protocol_name'] = decodeString($data);
    $offset = strlen($connect_info['protocol_name']) + 2;

    $connect_info['version'] = ord(substr($data, $offset, 1));
    $offset += 1;

    $byte = ord($data[$offset]);
    $connect_info['willRetain'] = ($byte & 0x20 == 0x20);
    $connect_info['willQos'] = ($byte & 0x18 >> 3);
    $connect_info['willFlag'] = ($byte & 0x04 == 0x04);
    $connect_info['cleanStart'] = ($byte & 0x02 == 0x02);
    $offset += 1;

    $connect_info['keepalive'] = decodeValue(substr($data, $offset, 2));
    $offset += 2;
    $connect_info['clientId'] = decodeString(substr($data, $offset));
    return $connect_info;
}

$server = new Swoole\Server("127.0.0.1", 9501, SWOOLE_BASE);

$server->set([
    'open_mqtt_protocol' => TRUE,
    'worker_num' => 1,
]);

$server->on('connect', function ($server, $fd) {
    echo "Client:Connect.\n";
});

$server->on('receive', function ($server, $fd, $from_id, $data) {
    $header = mqttGetHeader($data);

    if ($header['type'] == 1) {
        $resp = chr(32) . chr(2) . chr(0) . chr(0);
        eventConnect($header, substr($data, 2));
        $server->send($fd, $resp);
    } elseif ($header['type'] == 3) {
        $offset = 2;
        $topic = decodeString(substr($data, $offset));
        $offset += strlen($topic) + 2;
        $msg = substr($data, $offset);
        echo "client msg: $topic\n----------\n$msg\n";
    }
    echo "received length=" . strlen($data) . "\n";
});

$server->on('close', function ($server, $fd) {
    echo "Client: Close.\n";
});

$server->start();