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
。相同的key
new 两次也只用一个 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);
}