Swoole\Client
Swoole\Client 以下简称 Client,提供了 TCP/UDP、socket 的客户端的封装代码,使用时仅需 new Swoole\Client 即可。可用于 FPM/Apache 环境。
相对传统的 streams 系列函数,有几大优势:
stream函数存在超时设置的陷阱和Bug,一旦没处理好会导致Server端长时间阻塞stream函数的fread默认最大8192长度限制,无法支持UDP的大包Client支持waitall,在有确定包长度时可一次取完,不必循环读取Client支持UDP Connect,解决了UDP串包问题Client是纯C的代码,专门处理socket,stream函数非常复杂。Client性能更好Client支持长连接- 可以使用 swoole_client_select 函数实现多个
Client的并发控制完整示例
不支持$client = new Swoole\Client(SWOOLE_SOCK_TCP);if (!$client->connect('127.0.0.1', 9501, -1)) {echo "connect failed. Error: {$client->errCode}\n";// 失败重连$client->close(true);$client->connect('127.0.0.1', 9501);}$client->send("hello world\n");echo $client->recv();$client->close();
Apache的prework多线程模式方法
__construct()
方法格式
Swoole\Client->__construct(int $sock_type, int $is_sync = SWOOLE_SOCK_SYNC, string $key);
参数介绍
int $sock_type
功能:表示
socket的类型【支持SWOOLE_SOCK_TCP、SWOOLE_SOCK_TCP6、SWOOLE_SOCK_UDP、SWOOLE_SOCK_UDP6】int $is_sync功能:同步阻塞模式,现在只有这一个类型,保留此参数只为了兼容 api
string $key功能:用于长连接的
Key【默认使用IP:PORT作为key。相同的keynew 两次也只用一个 TCP 连接】, 达到复用的目的.
在 PHP-FPM/Apache 中创建长连接
$cli = new Swoole\Client(SWOOLE_SOCK_TCP | SWOOLE_KEEP);
加入 SWOOLE_KEEP 标志后,创建的 TCP 连接在 PHP 请求结束或者调用 $cli->close() 时并不会关闭。下一次执行 connect 调用时会复用上一次创建的连接。长连接保存的方式默认是以 ServerHost:ServerPort 为 key 的。可以在第 3 个参数内指定 key。Client 对象析构会自动调用 close 方法关闭 socket
connect()
方法格式
Swoole\Client->connect(string $host, int $port, float $timeout = 0.5, int $flag = 0): bool
参数介绍
string $host
功能:服务器地址【支持自动异步解析域名,
$host可直接传入域名】int $port-
float $timeout 功能:设置超时时间
- 值单位: 秒【支持浮点型,如
1.5表示1s+500ms】 -
int $flag 在
UDP类型时表示是否启用udp_connect设定此选项后将绑定$host与$port,此UDP将会丢弃非指定host/port的数据包。- 在
TCP类型,$flag=1表示设置为非阻塞socket,之后此 fd 会变成异步 IO,connect会立即返回。如果将$flag设置为1,那么在send/recv前必须使用 swoole_client_select 来检测是否完成了连接。
默认底层并不会启用 udp connect,一个 UDP 客户端执行 connect 时,底层在创建 socket 后会立即返回成功。这时此 socket 绑定的地址是 0.0.0.0,任何其他对端均可向此端口发送数据包。
如 $client->connect('192.168.1.100', 9502),这时操作系统为客户端 socket 随机分配了一个端口 58232,其他机器,如 192.168.1.101 也可以向这个端口发送数据包。
未开启 udp connect,调用 getsockname 返回的 host 项为 0.0.0.0
启用 udp connect,$client->connect('192.168.1.100', 9502, 1, 1)。这时将会绑定客户端和服务器端,底层会根据服务器端的地址来绑定 socket 绑定的地址。如连接了 192.168.1.100,当前 socket 会被绑定到 192.168.1.* 的本机地址上。启用 udp connect 后,客户端将不再接收其他主机向此端口发送的数据包。
返回值
- 成功返回
true - 失败返回
false,请检查errCode属性获取失败原因失败重连
connect失败后如果希望重连一次,必须先进行close关闭旧的socket,否则会返回EINPROCESS错误,因为当前的socket正在连接服务器,客户端并不知道是否连接成功,所以无法再次执行connect。调用close会关闭当前的socket,底层重新创建新的socket来进行连接。if ($socket->connect('127.0.0.1', 9502) === false) {$socket->close(true);$socket->connect('127.0.0.1', 9502);}
