clue / quassel-react
基于ReactPHP构建的Quassel IRC核心的流式、事件驱动访问。
Requires
- php: >=5.3
- clue/qdatastream: ^0.8
- react/event-loop: ^1.0 || ^0.5 || ^0.4 || ^0.3
- react/promise: ~2.0|~1.1
- react/socket: ^1.0 || ^0.8 || ^0.7
- react/stream: ^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4.6
Requires (Dev)
- clue/block-react: ^1.1
- phpunit/phpunit: ^9.3 || ^5.7 || ^4.8.35
README
基于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结构,但实际上底层使用的是二进制线格式。此库以原样暴露了此解析结构,通常不对其进行任何更改。
对此规则只有少数明显的例外。
- 传入的缓冲区/频道和聊天消息使用复杂的数据模型,因此分别由
BufferInfo
和Message
表示。所有其他数据类型都使用纯结构化数据,因此您可以非常类似于JSON-like数据结构访问其基于对象的结构。 - 旧版协议使用纯时间作为心跳消息,而新数据流协议使用
DateTime
对象。出于一致性原因,此库始终将其转换为DateTime
。 - 初始
Network
同步使用不同的结构来表示IrcUsersAndChannels
格式结构,具体取决于使用的线协议。出于一致性原因,此库始终以更简单的“逻辑”形式公开此结构。这意味着它始终包含Users
和Channels
键,它们都包含描述每个元素的列表。
这基本上意味着您应该始终为旧版协议和新数据流协议获得一致的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)。
这个库从其他现有工具和库中汲取了一些灵感。因此,向以下存储库的作者致以崇高的敬意!