clue/quassel-react

基于ReactPHP构建的Quassel IRC核心的流式、事件驱动访问。

v0.7.0 2021-02-26 13:58 UTC

This package is auto-updated.

Last update: 2024-09-17 01:16:42 UTC


README

CI status installs on Packagist

基于ReactPHP的Quassel IRC核心的流式、事件驱动访问。

这是一个轻量级、低级别的网络库,可以用来与Quassel IRC核心通信。它允许您对传入的事件(如传入的消息)做出反应,并执行新的请求(如发送出去的回复消息)。这可以用来构建聊天机器人,导出频道存档,列出在线用户,将后端事件作为消息转发到频道,等等。与传统的IRC聊天机器人不同,Quassel IRC允许重用现有的身份,并与人和聊天机器人共享,这样外部人员就不知道这一点,只能看到一个联系人。

  • 异步执行请求 - 并行地向您的Quassel IRC核心发送任意数量的请求(自动管道),并在结果到来时立即处理它们的响应。
  • 事件驱动核心 - 将事件处理器回调注册到事件处理器中,以对传入的事件(如传入的聊天消息事件)做出反应。
  • 轻量级、SOLID设计 - 提供了一个薄的抽象层,这是恰到好处的,不会妨碍您。未来的或自定义命令和事件需要很少或不需要更改即可支持。
  • 良好的测试覆盖率 - 附带自动测试套件,并定期在实际的Quassel IRC核心上进行测试

目录

支持我们

我们投入了大量时间开发、维护和更新我们的优秀开源项目。您可以通过在GitHub上成为赞助商来帮助我们维持工作的高质量。赞助商将获得许多回报,有关详细信息,请参阅我们的赞助页面

让我们一起将这些项目提升到新的水平!🚀

快速入门示例

Quassel IRC协议并不容易解释,并且有一些有趣的消息语义。因此,强烈建议查看示例以开始。

用法

工厂

Factory负责创建您的Client实例。

$factory = new Clue\React\Quassel\Factory();

此类接受一个可选的LoopInterface|null $loop参数,可以用来将事件循环实例传递给此对象。您可以使用null值,以使用默认循环。除非您确定确实想显式使用给定的事件循环实例,否则不应提供此值。

如果您需要自定义连接器设置(DNS解析、TLS参数、超时、代理服务器等),可以显式传递ConnectorInterface的自定义实例。

$connector = new React\Socket\Connector(array(
    'dns' => '127.0.0.1',
    'tcp' => array(
        'bindto' => '192.168.10.1:0'
    ),
    'tls' => array(
        'verify_peer' => false,
        'verify_peer_name' => false
    )
));

$factory = new Clue\React\Quassel\Factory(null, $connector);

createClient()

createClient($uri) 方法可以用来创建一个新的 Client。它有助于建立到您的 Quassel IRC 核心的纯 TCP/IP 连接,并探测使用正确的协议。

$factory->createClient('localhost')->then(
    function (Client $client) {
        // client connected (and authenticated)
    },
    function (Exception $e) {
        // an error occured while trying to connect (or authenticate) client
    }
);

$uri 参数必须是一个有效的 URI,它必须包含主机部分,并且可以选择性地以 quassel:// URI 方案开头,如果您的 Quassel IRC 核心没有使用默认的 TCP/IP 端口 4242,则可以包含端口号。

$factory->createClient('quassel://localhost:4242');

Quassel 支持基于密码的认证。如果您想创建一个“普通”的客户端连接,建议您将认证细节作为 URI 的一部分传递。您可以像这样将密码 h@llo URL 编码(百分编码)作为 URI 的一部分传递:

$factory->createClient('quassel://user:h%40llo@localhost')->then(
    function (Client $client) {
        // client sucessfully connected and authenticated
        $client->on('data', function ($data) {
            // next message to follow would be "SessionInit"
        });
    }
);

请注意,如果您没有将认证细节作为 URI 的一部分传递,那么此方法将在连接后立即解析出一个“裸”的 Client,而不会发送任何应用程序消息。这在您需要完全控制消息流时很有用,下面将提供更多详细信息。

Quassel 使用“心跳”消息作为保持连接活跃的机制,以检查 Quassel 核心与 Quassel 客户端之间的连接是否仍然活跃。此项目将自动对每个传入的“ping”(心跳请求)以适当的“pong”(心跳响应)消息进行响应。如果您不希望这样做,并想自己处理传入的心跳请求消息,则可以像这样传递可选的 ?pong=0 参数。

$factory->createClient('quassel://localhost?pong=0');

此自动“pong”机制允许 Quassel 核心检测到客户端的连接仍然活跃。但是,它不允许客户端检测到连接到 Quassel 核心的连接是否仍然活跃。因此,此项目将在默认情况下在 60 秒内没有收到任何消息后自动向 Quassel 核心发送一个“ping”(心跳请求)消息。如果在等待另一段时间后仍未收到任何消息,则假定连接已死亡并将关闭。您可以通过传递 ?ping=120.0 参数来更改此默认间隔。Quassel 核心默认使用可配置的 ping 间隔 30 秒,并将所有 IRC 网络状态更改发送到客户端,因此此机制只有在看起来连接已死亡时才会真正启动。如果您不希望这样做,并想自己处理发出的心跳请求消息,则可以传递可选的 ?ping=0 参数。

$factory->createClient('quassel://localhost?ping=0');

此方法使用 Quassel IRC 的探测机制来使用正确的协议(较新的“数据流”协议或原始的“遗产”协议)。协议处理将为您抽象,因此您不必担心这一点(有关协议消息的更多详细信息,请参阅以下内容)。

客户端

Client 负责与您的 Quassel IRC 核心交换消息并发出传入的消息。它实现了 DuplexStreamInterface,即它既是一个正常的可读流实例,也是一个可写流实例。

命令

Client 提供了一些公共方法,可以用来向您的 Quassel IRC 核心发送输出命令。

$client->writeClientInit()
$client->writeClientLogin($user, $password);

$client->writeHeartBeatRequest($time);
$client->writeHeartBeatReply($time);

$client->writeBufferRequestBacklog($bufferId, $messageIdFirst, $messageIdLast, $maxAmount, $additional);
$client->writeBufferRequestBacklogAll($messageIdFirst, $messageIdLast, $maxAmount, $additional);
$client->writeBufferInput($bufferInfo, $input);

// many more…

在此处列出所有可用的命令超出了范围,请参阅 类概述

处理

发送命令是异步的(非阻塞的),因此您可以实际上并行发送多个命令。您可以在并行中发送多个命令,待处理的命令将自动流水线化。

Quassel IRC有一些有趣的协议语义,这意味着命令不使用请求-响应样式。一些命令将触发发送响应消息,更多详情请见on()

on()

可以使用on($eventName, $eventHandler)方法来注册新的事件处理程序。传入的事件将被转发到已注册的事件处理程序回调。

$client->on('data', function ($data) {
    // process an incoming message (raw message object or array)
    var_dump($data);
});

$client->on('end', function () {
    // connection ended, client will close
});

$client->on('error', function (Exception $e) {
    // an error occured, client will close
});

$client->on('close', function () {
    // the connection to Quassel IRC just closed
});

data事件将转发远程Quassel IRC核心发送到客户端的PHP表示形式。从消费者角度来看,这看起来非常类似于解析后的JSON结构,但实际上底层使用的是二进制线格式。此库以原样暴露了此解析结构,通常不对其进行任何更改。

对此规则只有少数明显的例外。

  • 传入的缓冲区/频道和聊天消息使用复杂的数据模型,因此分别由BufferInfoMessage表示。所有其他数据类型都使用纯结构化数据,因此您可以非常类似于JSON-like数据结构访问其基于对象的结构。
  • 旧版协议使用纯时间作为心跳消息,而新数据流协议使用DateTime对象。出于一致性原因,此库始终将其转换为DateTime
  • 初始Network同步使用不同的结构来表示IrcUsersAndChannels格式结构,具体取决于使用的线协议。出于一致性原因,此库始终以更简单的“逻辑”形式公开此结构。这意味着它始终包含UsersChannels键,它们都包含描述每个元素的列表。

这基本上意味着您应该始终为旧版协议和新数据流协议获得一致的data事件。

close()

可以使用close()方法强制立即关闭Quassel连接。

安装

推荐通过Composer安装此库。 对Composer不熟悉?

这将安装最新支持的版本。

$ composer require clue/quassel-react:^0.7

有关版本升级的详细信息,请参阅CHANGELOG

此项目旨在在任何平台上运行,因此不需要任何PHP扩展,并支持从旧版PHP 5.3到当前PHP 8+和HHVM的运行。强烈建议为此项目使用PHP 7+。

内部,它将使用ext-mbstring在消息字符串之间进行不同字符编码的转换。如果此扩展不存在,则此库将使用稍微慢一点的Regex工作方式,但应该在其他方面同样有效。强烈建议安装ext-mbstring

测试

要运行测试套件,首先需要克隆此仓库,然后通过Composer安装所有依赖项。

$ composer install

要运行测试套件,请转到项目根目录并运行

$ php vendor/bin/phpunit

测试套件包含单元测试和功能集成测试。功能测试需要访问运行的Quassel核心服务器实例,默认情况下将跳过。

请注意,功能测试套件包含设置您的Quassel核心的测试(即,如果您尚未存在,则注册您的初始用户)。如果核心已设置,则此测试将跳过。如果您想对此进行测试,可以使用Docker容器

$ docker run -it --rm -p 4242:4242 clue/quassel-core -d

如果您想运行功能测试,则需要提供您自己的Quassel登录凭据,如下所示

$ QUASSEL_HOST=127.0.0.1 QUASSEL_USER=quassel QUASSEL_PASS=secret phpunit

许可证

此项目在MIT许可证下发布。

您知道吗?我提供定制开发服务,并为发行版赞助和贡献开具发票。有关详细信息,请联系我(@clue)。

这个库从其他现有工具和库中汲取了一些灵感。因此,向以下存储库的作者致以崇高的敬意!