ricardoooo0/mqtt-client

php-mqtt/client的副本添加psr/log 1.0

dev-main 2022-07-01 06:52 UTC

This package is auto-updated.

Last update: 2024-09-29 05:50:11 UTC


README

Latest Stable Version Total Downloads Coverage Quality Gate Status Maintainability Rating Reliability Rating Security Rating Vulnerabilities License

php-mqtt/clientMarvin Mall创建并维护。它允许您连接到MQTT代理,在那里您可以发布消息并订阅主题。当前的实现支持所有QoS级别(带有限制)。

安装

该软件包可在packagist.org上找到,可以使用composer进行安装。

composer require php-mqtt/client

该软件包需要PHP版本7.4或更高版本。

用法

以下仅给出一些非常基本的示例。对于更详细的示例,请参阅php-mqtt/client-examples仓库

发布

使用QoS 0的基本发布示例只需要三个步骤:连接、发布和断开连接

$server   = 'some-broker.example.com';
$port     = 1883;
$clientId = 'test-publisher';

$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
$mqtt->connect();
$mqtt->publish('php-mqtt/client/test', 'Hello World!', 0);
$mqtt->disconnect();

如果您不传递$clientId,则会为您生成一个随机的客户端ID。这基本上会隐式强制一个干净会话。

请注意,大多数方法都可能抛出异常。上述示例没有添加任何异常处理以简化说明。

订阅

订阅比发布更复杂,因为它需要运行事件循环,该循环读取、解析和处理来自代理的消息

$server   = 'some-broker.example.com';
$port     = 1883;
$clientId = 'test-subscriber';

$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
$mqtt->connect();
$mqtt->subscribe('php-mqtt/client/test', function ($topic, $message) {
    echo sprintf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);
$mqtt->loop(true);
$mqtt->disconnect();

当循环活动时,您可以使用$mqtt->interrupt()向循环发送中断信号。这将终止循环,在它开始下一次迭代之前。例如,您可以使用pcntl_signal(SIGINT, $handler)调用此方法。

pcntl_async_signals(true);

$clientId = 'test-subscriber';

$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);
pcntl_signal(SIGINT, function (int $signal, $info) use ($mqtt) {
    $mqtt->interrupt();
});
$mqtt->connect();
$mqtt->subscribe('php-mqtt/client/test', function ($topic, $message) {
    echo sprintf("Received message on topic [%s]: %s\n", $topic, $message);
}, 0);
$mqtt->loop(true);
$mqtt->disconnect();

客户端设置

如上例所示,MqttClient接受服务器、端口和客户端ID作为前三个参数。作为第四个参数,可以传递协议级别。目前支持的是MQTT v3.1,作为常量MqttClient::MQTT_3_1提供。第五个参数允许传递存储库(默认情况下,只有MemoryRepository可用)。最后,可以传递第六个参数作为日志记录器。如果没有提供,则使用null日志记录器。

示例

$mqtt = new \PhpMqtt\Client\MqttClient(
    $server, 
    $port, 
    $clientId,
    \PhpMqtt\Client\MqttClient::MQTT_3_1,
    new \PhpMqtt\Client\Repositories\MemoryRepository(),
    new Logger()
);

Logger必须实现Psr\Log\LoggerInterface

连接设置

MqttClientconnect()方法接受两个可选参数

  1. 一个ConnectionSettings实例
  2. 一个布尔标志,指示是否应请求干净会话(随机客户端ID会隐式执行此操作)

示例

$mqtt = new \PhpMqtt\Client\MqttClient($server, $port, $clientId);

$connectionSettings = (new \PhpMqtt\Client\ConnectionSettings)
    ->setConnectTimeout(3)
    ->setUseTls(true)
    ->setTlsSelfSignedAllowed(true);
    
$mqtt->connect($connectionSettings, true);

ConnectionSettings类通过流畅的接口提供了一些设置。该类型本身是不可变的,并且将为每个添加的选项创建一个新的ConnectionSettings实例。这还可以防止在连接建立后更改连接设置。

以下是选项的完整列表及其相应的默认值

$connectionSettings = (new \PhpMqtt\Client\ConnectionSettings)

    // The username used for authentication when connecting to the broker.
    ->setUsername(null)
    
    // The password used for authentication when connecting to the broker.
    ->setPassword(null)
    
    // The connect timeout defines the maximum amount of seconds the client will try to establish
    // a socket connection with the broker. The value cannot be less than 1 second.
    ->setConnectTimeout(60)
    
    // The socket timeout is the maximum amount of idle time in seconds for the socket connection.
    // If no data is read or sent for the given amount of seconds, the socket will be closed.
    // The value cannot be less than 1 second.
    ->setSocketTimeout(5)
    
    // The resend timeout is the number of seconds the client will wait before sending a duplicate
    // of pending messages without acknowledgement. The value cannot be less than 1 second.
    ->setResendTimeout(10)
    
    // This flag determines whether the client will try to reconnect automatically
    // if it notices a disconnect while sending data.
    // The setting cannot be used together with the clean session flag.
    ->setReconnectAutomatically(false)
    
    // Defines the maximum number of reconnect attempts until the client gives up.
    // This setting is only relevant if setReconnectAutomatically() is set to true.
    ->setMaxReconnectAttempts(3)
    
    // The keep alive interval is the number of seconds the client will wait without sending a message
    // until it sends a keep alive signal (ping) to the broker. The value cannot be less than 1 second
    // and may not be higher than 65535 seconds. A reasonable value is 10 seconds (the default).
    ->setKeepAliveInterval(10)
    
    // If the broker should publish a last will message in the name of the client when the client
    // disconnects abruptly, this setting defines the topic on which the message will be published.
    //
    // A last will message will only be published if both this setting as well as the last will
    // message are configured.
    ->setLastWillTopic(null)
    
    // If the broker should publish a last will message in the name of the client when the client
    // disconnects abruptly, this setting defines the message which will be published.
    //
    // A last will message will only be published if both this setting as well as the last will
    // topic are configured.
    ->setLastWillMessage(null)
    
    // The quality of service level the last will message of the client will be published with,
    // if it gets triggered.
    ->setLastWillQualityOfService(0)
    
    // This flag determines if the last will message of the client will be retained, if it gets
    // triggered. Using this setting can be handy to signal that a client is offline by publishing
    // a retained offline state in the last will and an online state as first message on connect.
    ->setRetainLastWill(false)
    
    // This flag determines if TLS should be used for the connection. The port which is used to
    // connect to the broker must support TLS connections.
    ->setUseTls(false)
    
    // This flag determines if the peer certificate is verified, if TLS is used.
    ->setTlsVerifyPeer(true)
    
    // This flag determines if the peer name is verified, if TLS is used.
    ->setTlsVerifyPeerName(true)
    
    // This flag determines if self signed certificates of the peer should be accepted.
    // Setting this to TRUE implies a security risk and should be avoided for production
    // scenarios and public services.
    ->setTlsSelfSignedAllowed(false)
    
    // The path to a Certificate Authority certificate which is used to verify the peer
    // certificate, if TLS is used.
    ->setTlsCertificateAuthorityFile(null)
    
    // The path to a directory containing Certificate Authority certificates which are
    // used to verify the peer certificate, if TLS is used.
    ->setTlsCertificateAuthorityPath(null)
    
    // The path to a client certificate file used for authentication, if TLS is used.
    //
    // The client certificate must be PEM encoded. It may optionally contain the
    // certificate chain of issuers.
    ->setTlsClientCertificateFile(null)
    
    // The path to a client certificate key file used for authentication, if TLS is used.
    //
    // This option requires ConnectionSettings::setTlsClientCertificateFile() to be used as well.
    ->setTlsClientCertificateKeyFile(null)
    
    // The passphrase used to decrypt the private key of the client certificate,
    // which in return is used for authentication, if TLS is used.
    //
    // This option requires ConnectionSettings::setTlsClientCertificateFile() and
    // ConnectionSettings::setTlsClientCertificateKeyFile() to be used as well.
    ->setTlsClientCertificateKeyPassphrase(null);

功能

  • 支持的MQTT版本
    • v3(不要使用v3.1功能,如用户名和密码)
    • v3.1
    • v3.1.1
    • v5.0
  • 传输
    • TCP(未加密)
    • TLS(加密,使用证书颁发机构文件验证对等方)
  • 连接
    • 最后意愿
    • 消息保留
    • 身份验证(用户名和密码)
    • TLS加密连接
    • 清理会话(可以设置并发送,但客户端对QoS 2消息没有持久化存储)
  • 发布
    • QoS等级0
    • QoS等级1(限制:会话间没有持久化状态)
    • QoS等级2(限制:会话间没有持久化状态)
  • 订阅
    • QoS等级0
    • QoS等级1
    • QoS等级2(限制:会话间没有持久化状态)
  • 支持的消息长度:无限制 (没有强制限制,尽管MQTT协议支持最多256MB,但无论如何都不应该使用)
  • 支持日志记录(可以将Psr\Log\LoggerInterface传递给客户端)
  • 持久化驱动程序
    • 内存驱动程序
    • Redis驱动程序

限制

  • 具有高于0的QoS等级的消息不会进行持久化,因为默认实现使用内存存储库来存储数据。为了避免消息流损坏的问题,使用清理会话标志来表示你不在乎旧数据。这不仅可以指示代理器考虑新的连接(没有先前状态),而且还会重置已注册的存储库。

开发与测试

证书(TLS)

要运行测试(尤其是TLS测试),你需要创建证书。这里提供了一个命令来完成这个任务

sh create-certificates.sh

这将创建在.ci/tls/目录下所需的所有证书。同样,这个脚本也用于持续集成。

测试用例的MQTT代理

运行测试预期MQTT代理正在运行。运行MQTT代理最简单的方法是通过Docker

docker run --rm -it -p 1883:1883 -p 8883:8883 -p 8884:8884 -v $(pwd)/.ci/tls:/mosquitto-certs -v $(pwd)/.ci/mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto:1.6

从项目目录运行时,这将启动一个Mosquitto MQTT代理,配置为使用生成的TLS证书和自定义配置。

如果你打算运行不同的代理或使用不同的方法,或者使用公共代理,你需要相应地调整在phpunit.xml中定义的环境变量。

许可证

php-mqtt/client是开源软件,根据MIT许可证授权。