edefimov / async-sockets
基于php流的异步socket操作库
0.3.0
2016-04-10 11:13 UTC
Requires
- php: >=5.4
Requires (Dev)
- symfony/console: ~2.7 || ~3.0
- symfony/event-dispatcher: ~2.7 || ~3.0
- symfony/yaml: ~2.7 || ~3.0
Suggests
- ext-libevent: For using RequestExecutor engine based on libevent
- symfony/event-dispatcher: Allows to notify system about socket events
This package is auto-updated.
Last update: 2024-09-09 01:31:59 UTC
README
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();
查看完整示例 这里