edefimov/async-sockets

基于php流的异步socket操作库

0.3.0 2016-04-10 11:13 UTC

This package is auto-updated.

Last update: 2024-09-09 01:31:59 UTC


README

Build Status Documentation Status Scrutinizer Coverage SensioLabsInsight Scrutinizer GitHub release Dependency Status Downloads Minimum PHP Version

Async sockets 是基于php流的socket异步操作的事件驱动库。

特性

  • 同时执行多个请求
  • 区分帧边界
  • 支持服务器socket
  • 支持持久连接
  • 支持对同一主机:端口建立多个持久连接
  • 异步处理TLS握手
  • socket之间的同步
  • 确定UDP socket的数据报大小
  • 支持stream_get_transports返回的所有传输方式
  • 与symfony事件调度器组件兼容
  • 完全控制超时
  • 在执行过程中动态添加新请求
  • 为每个socket设置单独的超时值
  • 通过php流上下文自定义socket设置
  • 为每个socket设置自定义用户上下文
  • 停止特定socket或所有socket的请求
  • 限制运行请求数量的策略
  • 错误处理基于异常
  • 支持libevent引擎

用途

Async sockets库为应用程序提供网络层,隐藏I/O操作的复杂性,并负责连接管理。该库将成为在PHP上实现任意网络协议以及实现服务器的强大基础。同时运行多个请求可以减少I/O操作的延迟,达到最慢服务器的超时时间。

文档

稳定版本

最新版本

安装

推荐通过composer安装async sockets库

稳定版本

$ composer require edefimov/async-sockets:~0.3.0 --prefer-dist|--prefer-source

实际版本

$ composer require edefimov/async-sockets:dev-master

在生产环境中使用--prefer-dist选项,以便忽略测试和示例文件的下载,而开发时使用--prefer-source选项。开发版本包括测试和示例文件。

快速入门

步骤1. 在需要开始请求的位置创建AsyncSocketFactory

$factory = new AsyncSocketFactory();

步骤2. 创建RequestExecutor和适当数量的socket

$client        = $factory->createSocket(AsyncSocketFactory::SOCKET_CLIENT);
$anotherClient = $factory->createSocket(AsyncSocketFactory::SOCKET_CLIENT);

$executor = $factory->createRequestExecutor();

步骤3. 创建事件处理程序,包含你感兴趣的事件

$handler = new CallbackEventHandler(
    [
        EventType::INITIALIZE   => [$this, 'onInitialize'],
        EventType::CONNECTED    => [$this, 'onConnected'],
        EventType::WRITE        => [$this, 'onWrite'],
        EventType::READ         => [$this, 'onRead'],
        EventType::ACCEPT       => [$this, 'onAccept'],
        EventType::DATA_ALERT   => [$this, 'onDataAlert'],
        EventType::DISCONNECTED => [$this, 'onDisconnected'],
        EventType::FINALIZE     => [$this, 'onFinalize'],
        EventType::EXCEPTION    => [$this, 'onException'],
        EventType::TIMEOUT      => [$this, 'onTimeout'],
    ]
);

步骤4. 将socket添加到RequestExecutor

$executor->socketBag()->addSocket(
    $client, 
    new WriteOperation(), 
    [
        RequestExecutorInterface::META_ADDRESS => 'tls://github.com:443',
        RequestExecutorInterface::META_CONNECTION_TIMEOUT => 30,
        RequestExecutorInterface::META_IO_TIMEOUT => 5,
    ],
    $handler
);
$executor->socketBag()->addSocket(
    $anotherClient, 
    new WriteOperation(), 
    [
        RequestExecutorInterface::META_ADDRESS => 'tls://packagist.org.cn:443',
        RequestExecutorInterface::META_CONNECTION_TIMEOUT => 10,
        RequestExecutorInterface::META_IO_TIMEOUT => 2,
    ],
    $handler
);

步骤5. 执行它!

$executor->executeRequest();

示例用法

客户端socket

$factory = new AsyncSocketFactory();

$client        = $factory->createSocket(AsyncSocketFactory::SOCKET_CLIENT);
$anotherClient = $factory->createSocket(AsyncSocketFactory::SOCKET_CLIENT);

$executor = $factory->createRequestExecutor();

$handler = new CallbackEventHandler(
    [
        EventType::INITIALIZE   => [$this, 'onInitialize'],
        EventType::CONNECTED    => [$this, 'onConnected'],
        EventType::WRITE        => [$this, 'onWrite'],
        EventType::READ         => [$this, 'onRead'],
        EventType::DISCONNECTED => [$this, 'onDisconnected'],
        EventType::FINALIZE     => [$this, 'onFinalize'],
        EventType::EXCEPTION    => [$this, 'onException'],
        EventType::TIMEOUT      => [$this, 'onTimeout'],
    ]
);

$executor->socketBag()->addSocket(
    $client, 
    new WriteOperation(), 
    [
        RequestExecutorInterface::META_ADDRESS => 'tls://github.com:443',
        RequestExecutorInterface::META_CONNECTION_TIMEOUT => 30,
        RequestExecutorInterface::META_IO_TIMEOUT => 5,
    ],
    $handler
);
$executor->socketBag()->addSocket(
    $anotherClient, 
    new WriteOperation(), 
    [
        RequestExecutorInterface::META_ADDRESS => 'tls://packagist.org.cn:443',
        RequestExecutorInterface::META_CONNECTION_TIMEOUT => 10,
        RequestExecutorInterface::META_IO_TIMEOUT => 2,
    ],
    $handler
);

$executor->executeRequest();

查看完整示例 这里

服务器socket

$factory       = new AsyncSocketFactory();
$serverSocket  = $factory->createSocket(AsyncSocketFactory::SOCKET_SERVER);
$executor      = $factory->createRequestExecutor();

$executor->socketBag()->addSocket(
    $serverSocket,
    new ReadOperation(),
    [
        RequestExecutorInterface::META_ADDRESS            => "tcp://:10280", // or "udp://:10280"
        RequestExecutorInterface::META_CONNECTION_TIMEOUT => RequestExecutorInterface::WAIT_FOREVER,
        RequestExecutorInterface::META_IO_TIMEOUT         => RequestExecutorInterface::WAIT_FOREVER,
    ],
    new CallbackEventHandler(
        [
            EventType::ACCEPT => function (AcceptEvent $event){
                $event->getExecutor()->socketBag()->addSocket(
                    $event->getClientSocket(),
                    new ReadOperation(),
                    [ ],
                    // client handlers
                );
            }
        ]
    )
);

$executor->executeRequest();

查看完整示例 这里