hoa/socket

此包已被废弃且不再维护。未建议替代包。

Hoa\Socket 库。

1.17.05.16 2017-05-16 07:55 UTC

README

Hoa

Build status Code coverage Packagist License

Hoa 是一套 模块化可扩展结构化 的 PHP 库。
此外,Hoa 旨在成为工业界和研究界之间的桥梁。

Hoa\Socket

Help on IRC Help on Gitter Documentation Board

此库提供了一层抽象,用于构建安全、快速和模块化的客户端和服务器。

它将连接表示为一个流(请参阅Hoa\Stream),用于构建客户端和服务器。连接支持超时、选项、上下文、加密、远程信息等。这样的连接以及一个抽象的连接处理器,允许在同一个进程中“嵌入”和“合并”多个连接。

了解更多.

安装

使用 Composer,要将此库添加到依赖项中,您需要要求 hoa/socket

$ composer require hoa/socket '~1.0'

有关更多安装过程,请阅读 源码页面

测试

在运行测试套件之前,必须安装开发依赖项

$ composer install

然后,运行所有测试套件

$ vendor/bin/hoa test:run

有关更多信息,请阅读贡献者指南

快速使用

作为一个快速概述,我们将查看创建服务器和客户端以及介绍相应的 API。

背后的连接

服务器和客户端都扩展了一个连接,即 Hoa\Socket\Connection\Connection 类,它是由 Hoa\Stream 表示的流。后者提供了常见的流 API,其中包含读写方法(来自 Hoa\Stream\IStream\InHoa\Stream\IStream\Out 以及 Hoa\Stream\IStream\Pathable)。由于它也负责连接,因此我们可以操作底层套接字资源、超时、不同的标志、流上下文、加密、远程信息等。

要启动连接,我们将使用 connect 方法(构造函数本身不会启动连接)。对于服务器,我们通常更喜欢使用 connectAndWait 方法(见下文)。要停止连接,大多数情况下,我们将使用 disconnect 方法。

远程连接(客户端对服务器,服务器对客户端)由一个节点表示:一个包含有关远程连接的多个信息的对象。默认节点是 Hoa\Socket\Node 并且可以轻松扩展。要使用新节点,我们必须调用 Hoa\Socket\Connection\Connection::setNodeName 方法。

连接需要一个套接字URI,由Hoa\Socket\Socket类表示,以了解连接的位置。后者代表一个IPv4或IPv6地址、域名或路径(对于Unix套接字),以及传输方案(tcp://udp://等)和端口号。

操纵服务器或客户端

我们将实例化Hoa\Socket\Server类,并连接到tcp://127.0.0.1:4242。然后,为了选择活动节点,我们将使用Hoa\Socket\Connection\Connection::select方法,该方法返回一个迭代器。最后,我们将读取一行并写入大写回声。因此

$server = new Hoa\Socket\Server('tcp://127.0.0.1:4242');
$server->connectAndWait();

while (true) {
    foreach ($server->select() as $node) {
        $line = $server->readLine();

        if (empty($line)) {
            $server->disconnect();
            continue;
        }

        echo '< ', $line, "\n";
        $server->writeLine(strtoupper($line));
    }
}

然后,使用telnet

$ telnet 127.0.0.1 4242
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
foobar
FOOBAR
hello world
HELLO WORLD

从服务器端,我们将看到

< foobar
< hello world

为了以我们自己的客户端复制相同的行为,我们将编写(多亏了Hoa\Console\Readline\Readline,请参阅Hoa\Console

$client = new Hoa\Socket\Client('tcp://127.0.0.1:4242');
$client->connect();

$readline = new Hoa\Console\Readline\Readline();

while (true) {
    $line = $readline->readLine('> ');

    if ('quit' === $line) {
        break;
    }

    $client->writeLine($line);

    echo '< ', $client->readLine(), "\n";
}

最后

$ php Client.php
> foobar
< FOOBAR
> hello world
< HELLO WORLD
> quit

处理服务器和客户端

连接具有高级操作,但它们是底层的,并不明显。此外,有一些我们需要经常重复且不太简单的工作,例如广播消息。Hoa\Socket\Connection\Handler提供了一种简单的方法来创建和嵌入一个非常灵活的服务器或客户端。(一个很好的完整示例是Hoa\Websocket)。

我们将关注服务器。服务器有一个神奇的run方法,该方法启动一个无限循环并在活动节点上进行一些计算。这基本上是我们之前示例中的while (true)。此外,我们希望能够轻松地向特定节点发送消息,或者向所有节点(除一个外)发送消息。Hoa\Socket\Connection\Handler类要求用户实现两个方法:_run_send,并提供run方法,以及sendbroadcast。然后,我们不再需要启动连接或关注不同网络拓扑的实现。所有这些都由处理程序管理。因此

class MyServer extends Hoa\Socket\Connection\Handler
{
    protected function _run (Hoa\Socket\Node $node)
    {
        $connection = $node->getConnection();
        $line       = $connection->readLine();

        if (empty($line)) {
            $connection->disconnect();
            return;
        }

        echo '< ', $line, "\n";
        $this->send(strtoupper($line));

        return;
    }

    protected function _send ($message, Hoa\Socket\Node $node)
    {
        return $node->getConnection()->writeLine($message);
    }
}

然后,我们只需要做的是

$server = new MyServer(new Hoa\Socket\Server('tcp://127.0.0.1:4242'));
$server->run();

我们看到连接被嵌入到我们的服务器中,并且所有逻辑都已移动到_run方法中。如果我们将send的调用更改为broadcast,我们将看到所有已连接的客户端接收消息,类似于

        echo '< ', $line, "\n";
        $this->broadcast(strtoupper($line));

_send方法提供了“发送一条消息”的实现,这是基础。因为_run方法没有启动无限循环,所以我们有更多的灵活性(请参阅下一节)。

我们可以添加监听器(请参阅Hoa\Event)以与服务器交互,类似于$server->on('message', function ( … ) { … });等。

合并连接

使用处理程序的一个巨大优势是它们可以用在Hoa\Socket\Connection\Group对象中。run方法是一个无限循环,因此我们无法在同一进程中并行运行两个服务器。幸运的是,Hoa\Socket\Connection\Group允许“合并”连接(这是Hoa\Socket\Connection\Connection的底层功能,但组抽象并管理所有复杂性)。因此,我们能够在同一进程中同时运行多个服务器和客户端。

例如,我们将运行一个 Hoa\Irc\Client 的实例(请参阅 Hoa\Irc),并使用一个 Hoa\Websocket\Server(请参阅 Hoa\Websocket):所有由 WebSocket 服务器接收的消息都将被重定向到 IRC 客户端。因此

$websocket = new Hoa\Websocket\Server(new Hoa\Socket\Server('tcp://…'));
$irc       = new Hoa\Irc\Client(new Hoa\Socket\Client('tcp://…'));
$group     = new Hoa\Socket\Connection\Group();
$group[]   = $websocket;
$group[]   = $irc;

$websocket->on(
    'message',
    function (Hoa\Event\Bucket $bucket) use ($irc) {
        $data = $bucket->getData();
        $irc->say($data['message']);

        return;
    }
);

// $irc->…

$group->run();

这是 Hoa\Socket\Connection 类提供的强大功能的说明。

文档

《Hoa\Socket》的黑客手册包含了关于如何使用此库及其工作原理的详细信息。

要本地生成文档,请执行以下命令

$ composer require --dev hoa/devtools
$ vendor/bin/hoa devtools:documentation --open

更多文档可以在项目网站上找到: hoa-project.net

获取帮助

主要有两种方式可以获得帮助

贡献

你想贡献吗?谢谢!详细的 贡献指南 解释了你需要知道的一切。

许可

Hoa 采用新 BSD 许可证(BSD-3-Clause)。请参阅 LICENSE 获取详细信息。

相关项目

以下项目正在使用此库

  • PHP School,学习 PHP 的一种革命性新方法。