swooleMqtt.php 3.24 KB
Newer Older
冯超鹏's avatar
冯超鹏 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
<?php

namespace App\Console\Commands;

use App\Http\Controllers\Auth\SwooleCommandController;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class swooleMqtt extends Command
{
    public $mqtt;
    protected $signature = 'swooleMqtt {action?}';
    protected $description = 'swooleMqtt';
    public function __construct()
    {
        parent::__construct();
    }
    public function handle()
    {
        $action = $this->argument('action');
        switch ($action) {
            case 'close':
                break;
            default:
                $this->start();//开启mqtt服务
                break;
        }

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

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

    public 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;
    }

    public function eventConnect($header, $data)
    {
        $connect_info['protocol_name'] = $this->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'] = $this->decodeValue(substr($data, $offset, 2));
        $offset += 2;
        $connect_info['clientId'] = $this->decodeString(substr($data, $offset));
        return $connect_info;
    }
    public function start()
    {
冯超鹏's avatar
冯超鹏 committed
75
        $this->mqtt = new \swoole_server("0.0.0.0", 9506, SWOOLE_BASE,SWOOLE_SOCK_TCP | SWOOLE_SSL);
冯超鹏's avatar
冯超鹏 committed
76 77 78 79 80 81 82 83 84
        $this->mqtt->set([
            'open_mqtt_protocol' => true, // 启用 mqtt 协议
            'worker_num' => 1,
        ]);
        $this->mqtt->on('connect', function ($server, $fd) {
            echo "Client:Connect.\n";
        });
        $this->mqtt->on('receive', function ($server, $fd, $from_id, $data) {
            $header = $this->mqttGetHeader($data);
85
            print_r($data);
冯超鹏's avatar
冯超鹏 committed
86 87 88
            if ($header['type'] == 1) {
                $resp = chr(32) . chr(2) . chr(0) . chr(0);
                $this->eventConnect($header, substr($data, 2));
89
//                print_r($resp);
冯超鹏's avatar
冯超鹏 committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
                $this->mqtt->send($fd, $resp);
            } elseif ($header['type'] == 3) {
                $resp = chr(32) . chr(2) . chr(0) . chr(0);
                $this->eventConnect($header, substr($data, 2));
                $this->mqtt->send($fd, $resp);
                print_r($data);
                //file_put_contents(__DIR__.'/data.log', $data);
            }
            echo "received length=" . strlen($data) . "\n";
        });

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