Skip to content

Commit

Permalink
Add getLevel (#55)
Browse files Browse the repository at this point in the history
* Add getLevel

* Add getLevel example
  • Loading branch information
sy-records authored Sep 12, 2021
1 parent 6b1b136 commit 5c5505a
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 13 deletions.
18 changes: 5 additions & 13 deletions docs/zh-cn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,13 @@ composer require simps/mqtt

参考 [examples](https://github.com/simps/mqtt/tree/master/examples) 目录

## 捐献及赞助 :id=donate
## 关注

### 一次性赞助
![](https://cdn.jsdelivr.net/gh/sy-records/staticfile/images/202012/wechat_white.png)

如果您是个人开发者并且 PHPMQTT 给您解决燃眉之急或带来些许明朗,您可以打赏一杯咖啡或一杯香茗 :)
## 赞赏 :id=donate

我们通过以下方式接受赞助:
如果给您解决燃眉之急或带来些许明朗,您可以打赏一杯咖啡或一杯香茗 :)

![alipay](https://cdn.jsdelivr.net/gh/sy-records/staticfile/images/alipay.jpg ':size=362x562')
![wechat](https://cdn.jsdelivr.net/gh/sy-records/staticfile/images/wechatpay.png ':size=autox562')
[donate](https://donate.qq52o.me/ ':include :type=iframe')

### 周期性赞助

如果您是企业经营者并且将 PHPMQTT 用在商业产品中,那么赞助 PHPMQTT 有商业上的益处:可以让您的产品所依赖的类库保持健康并得到积极的升级维护,也能获得一些技术支持。

周期性赞助可以获得额外的回报,比如您的名字或组织/公司 Logo 及链接会出现在 PHPMQTT 的 GitHub 仓库中。

> 如您希望为 PHPMQTT 提供周期性的赞助,可邮件至 [email protected]
51 changes: 51 additions & 0 deletions examples/getLevel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* This file is part of Simps
*
* @link https://github.com/simps/mqtt
* @contact Lu Fei <[email protected]>
*
* For the full copyright and license information,
* please view the LICENSE file that was distributed with this source code
*/

include __DIR__ . '/bootstrap.php';

use Simps\MQTT\Protocol\Types;
use Simps\MQTT\Protocol\V3;
use Simps\MQTT\Protocol\V5;
use Simps\MQTT\Tools\UnPackTool;
use Simps\MQTT\Protocol\ProtocolInterface;

$server = new Swoole\Server('127.0.0.1', 1883, SWOOLE_BASE);

$server->set(
[
'open_mqtt_protocol' => true,
'worker_num' => 1,
'package_max_length' => 2 * 1024 * 1024,
]
);

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

$server->on('receive', function (Swoole\Server $server, $fd, $from_id, $data) {
$type = UnPackTool::getType($data);
if ($type === Types::CONNECT) {
$level = UnPackTool::getLevel($data);
$class = $level === ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0 ? V5::class : V3::class;
$server->fds[$fd] = ['level' => $level, 'class' => $class];
}
/** @var ProtocolInterface $unpack */
$unpack = $server->fds[$fd]['class'];
var_dump($unpack::unpack($data));
});

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

$server->start();
19 changes: 19 additions & 0 deletions src/Tools/UnPackTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

namespace Simps\MQTT\Tools;

use Simps\MQTT\Exception\InvalidArgumentException;
use Simps\MQTT\Exception\LengthException;
use Simps\MQTT\Protocol\Types;

class UnPackTool extends Common
{
Expand Down Expand Up @@ -97,4 +99,21 @@ public static function getRemaining(string $data): string

return substr($data, $headBytes, $remainingLength);
}

/**
* Get the MQTT protocol level.
*/
public static function getLevel(string $data): int
{
$type = static::getType($data);

if ($type !== Types::CONNECT) {
throw new InvalidArgumentException(sprintf('packet must be of type connect, %s given', Types::getType($type)));
}

$remaining = static::getRemaining($data);
$length = unpack('n', $remaining)[1];

return ord($remaining[$length + 2]);
}
}
47 changes: 47 additions & 0 deletions tests/Unit/ToolsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* This file is part of Simps
*
* @link https://github.com/simps/mqtt
* @contact Lu Fei <[email protected]>
*
* For the full copyright and license information,
* please view the LICENSE file that was distributed with this source code
*/

declare(strict_types=1);

namespace SimpsTest\MQTT\Unit;

use PHPUnit\Framework\TestCase;
use Simps\MQTT\Exception\InvalidArgumentException;
use Simps\MQTT\Protocol\ProtocolInterface;
use Simps\MQTT\Tools\UnPackTool;

/**
* @internal
* @coversNothing
*/
class ToolsTest extends TestCase
{
public function testGetLevel()
{
$connect_31 = '104400064d51497364700306000a001353696d70735f36313362316164323236626334001973696d70732d6d7174742f757365723030312f64656c6574650006627965627965';
$connect_311 = '104200044d5154540406000a001353696d70735f36313362313830323035636633001973696d70732d6d7174742f757365723030312f64656c6574650006627965627965';
$connect_50 = '106200044d515454050e000a0b110000003c21ffff22ffff001353696d70735f3631336231613330313962663213180000003c020000003c030004746573740101001973696d70732d6d7174742f757365723030312f64656c6574650006627965627965';
$this->assertSame(UnPackTool::getLevel(hex2bin($connect_31)), ProtocolInterface::MQTT_PROTOCOL_LEVEL_3_1);
$this->assertSame(UnPackTool::getLevel(hex2bin($connect_311)), ProtocolInterface::MQTT_PROTOCOL_LEVEL_3_1_1);
$this->assertSame(UnPackTool::getLevel(hex2bin($connect_50)), ProtocolInterface::MQTT_PROTOCOL_LEVEL_5_0);
}

public function testInvalidGetLevel()
{
try {
$connAck = '200200';
UnPackTool::getLevel(hex2bin($connAck));
} catch (\Throwable $ex) {
$this->assertInstanceOf(InvalidArgumentException::class, $ex);
$this->assertSame($ex->getMessage(), 'packet must be of type connect, connack given');
}
}
}

0 comments on commit 5c5505a

Please sign in to comment.