一、官方案例理解
Client端创建
Client提供了TCP/UDP socket的客户端的封装代码,使用时仅需 new Swoole\Client 即可。
同步阻塞客户端
$ client = new swoole_client(SWOOLE_SOCK_TCP);①
if (!$client->connect('127.0.0.1', 9501, -1))②
{
exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");③
echo $client->recv();④
$client->close();⑥
① 函数原型:
swoole_client->__construct(int $ sock_type, int $ is_sync = SWOOLE_SOCK_SYNC, string $ key);
• $ sock_type表示socket的类型,如TCP/UDP
• 使用$ sock_type | SWOOLE_SSL可以启用SSL加密
• $ is_sync表示同步阻塞还是异步非阻塞,默认为同步阻塞
• $ key用于长连接的Key,默认使用IP:PORT作为key。相同key的连接会被复用
swoole_client构造函数参数
• SWOOLE_SOCK_TCP 创建tcp socket
• SWOOLE_SOCK_TCP6 创建tcp ipv6 socket
• SWOOLE_SOCK_UDP 创建udp socket
• SWOOLE_SOCK_UDP6 创建udp ipv6 socket
• SWOOLE_SOCK_UNIX_DGRAM 创建unix dgram socket
• SWOOLE_SOCK_UNIX_STREAM 创建unix stream socket
• SWOOLE_SOCK_SYNC 同步客户端
• SWOOLE_SOCK_ASYNC 异步客户端
所以在官方案例第一步输入构造函数SWOOLE_SOCK_TCP 参数,就可以创建tcp对象
② 连接到远程服务器,函数原型:
bool $swoole_client->connect(string $host, int $port, float $timeout = 0.5, int $flag = 0)
connect方法接受4个参数:
• $ host是远程服务器的地址,1.10.0或更高版本已支持自动异步解析域名,$ host可直接传入域名
• $ port是远程服务器端口
• $ timeout是网络IO的超时,包括connect/send/recv,单位是s,支持浮点数。默认为0.5s,即500ms
• $ flag参数在UDP类型时表示是否启用udp_connect 设定此选项后将绑定$ host与$ port,此UDP将会丢弃非指定host/port的数据包。
• $ flag参数在TCP类型,$ flag=1表示设置为非阻塞socket,connect会立即返回。如果将$ flag设置为1,那么在send/recv前必须使用swoole_client_select来检测是否完成了连接
③ 发送数据到远程服务器,必须在建立连接后,才可向Server发送数据。函数原型:
int $swoole_client->send(string $data);
• $ data参数为字符串,支持二进制数据
• 成功发送返回的已发数据长度
• 失败返回false,并设置$ swoole_client->errCode
④ recv方法用于从服务器端接收数据。接受2个参数。函数原型为:
//低于1.7.22
string $swoole_client->recv(int $size = 65535, bool $waitall = 0);
//1.7.22或更高
string $swoole_client->recv(int $size = 65535, int $flags = 0);
• $ size,接收数据的缓存区最大长度,此参数不要设置过大,否则会占用较大内存
• $ waitall,是否等待所有数据到达后返回
如果设定了$ waitall就必须设定准确的$size,否则会一直等待,直到接收的数据长度达到 $ size
未设置 $ waitall=true时, $ size最大为64K
如果设置了错误的 $ size,会导致recv超时,返回 false
• 成功收到数据返回字符串
• 连接关闭返回空字符串
• 失败返回 false,并设置 $client->errCode属性
⑤ 关闭连接,函数原型为:
bool $swoole_client->close(bool $force = false);
操作成功返回 true。当一个swoole_client连接被close后不要再次发起connect。正确的做法是销毁当前的swoole_client,重新创建一个swoole_client并发起新的连接。
• 第一个参数设置为true表示强制关闭连接,可用于关闭SWOOLE_KEEP长连接
注意:同步阻塞客户端和异步阻塞客户端代码编写不一样
二、个人案例
服务器端代码
//创建Server对象,监听 127.0.0.1:9501端口
$serv = new Swoole\Server("127.0.0.1", 9501);
$serv->set(
array(
'worker_num'=>2,
)
);
//监听客户端连接进入
$serv->on('Connect', function ($serv, $fd) {
echo "第{$fd}个客户端连接成功!.\n";
});
//监听客户端发来的数据
$serv->on('Receive', function ($serv, $fd, $reactor_id, $data) {
$serv->send($fd, "这是fd值:{$fd}这是线程值:{$reactor_id},这是客户端发来的值:".$data);
});
//监听连接关闭事件
$serv->on('Close', function ($serv, $fd) {
echo "服务器端关闭成功!\n";
});
//启动服务器
$serv->start();
客户端代码
$client = new swoole_client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, -1))
{
exit("连接失败!: {$client->errCode}\n");
}
fwrite(STDOUT,"请你输入你要发给服务器端的数据:");
$msg=trim(fgets(STDIN));
$client->send("{$msg}\n");
echo $client->recv();
$client->close();
·fwrite(STDOUT,"请你输入你要发给服务器端的数据:");
·fgets(STDIN);
这两个函数完成了在客户端提示用户输入信息,并接受信息的操作。
打开服务器端服务
打开客户端
这时候服务端出现
客户端出现
这时向客户端输入“你好这是客户端”,服务器端返回给你数据,并关闭服务器