一、TCP服务端:
创建swoole_tcp_server值需要四步
1、构建server对象
2、设置运行时参数
3、设置事件回调
4、启动服务
代码如下:
<?php
/**
* +----------------------------------------------------------
* date: 2019\8\25 0025 11:01
* +----------------------------------------------------------
* author: Raoxiaoya
* +----------------------------------------------------------
* describe: TCP服务
* +----------------------------------------------------------
*/
// 1、构建server 对象
$server = new Swoole\Server('0.0.0.0', 9001, SWOOLE_BASE, SWOOLE_SOCK_TCP);
// 2、设置运行时参数
$server->set([
'worker_num' => 4,// 初始工作进程数
'daemonize' => false,// 是否后台运行,为了便于调试,设置为否
'backlog' => 128,// 最多同时有多少个等待accept的连接
]);
// 3、设置事件回调
/**
* 客户端连接上服务端时触发回调
* $fd int 1-1600w
*/
$server->on('connect', function($server, $fd){
echo 'connect successful ...'.PHP_EOL;
});
/**
* 接收到来自客户端的数据
* $reactorId int reactor线程ID
*/
$server->on('receive', function($server, $fd, $reactorId, $data){
echo $data;
echo 'receive data ...'.PHP_EOL;
$server->send($fd, "I am server".PHP_EOL);
});
/**
* 客户端关闭连接时触发回调
*/
$server->on('close', function($server, $fd){
echo 'close ...'.PHP_EOL;
});
// 4、启动服务
$server->start();
注释:
1、connect,receive,close回调是在worker进程中完成的,而不是主进程。
2、server 为 Swoole\Server
对象。
3、fd是连接的文件描述符,发送数据/关闭连接时需要此参数。
fd是TCP客户端连接的标识符,在Server实例中是唯一的,在多个进程内不会重复。
fd是一个自增数字,范围是1 ~ 1600万,fd超过1600万后会自动从1开始进行复用。
fd是复用的,当连接关闭后fd会被新进入的连接复用。
正在维持的TCP连接fd不会被复用。
如果业务中需要发送广播,需要用apc、redis、MySQL、memcache、Swoole\Table将fd的值保存起来。
4、$reactorId来自哪个Reactor线程。
5、UDP协议下只有onPacket事件,没有onConnect/onClose事件。
6、服务端的send是异步的,底层会自动监听可写,将数据逐步发送给客户端。
二、TCP同步客户端:
<?php
/**
* +----------------------------------------------------------
* date: 2019\8\25 0025 20:04
* +----------------------------------------------------------
* author: Raoxiaoya
* +----------------------------------------------------------
* describe: 同步客户端
* +----------------------------------------------------------
*/
$client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);
$ret = $client->connect('127.0.0.1', 9001, 0.1, 0);
if(!$ret){
die('connect failed'.PHP_EOL);
}
$client->send('I have connected'.PHP_EOL);
$response = $client->recv();
echo $response.PHP_EOL;
$client->close();
三、TCP异步客户端:
<?php
/**
* +----------------------------------------------------------
* date: 2019\8\25 0025 21:29
* +----------------------------------------------------------
* author: Raoxiaoya
* +----------------------------------------------------------
* describe: 异步客户端
* +----------------------------------------------------------
*/
$client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
// 既然是异步的,那每一步几乎都不能立即返回结果,所以基本都是注册回调事件来接受结果
/**
* 服务端处理完此连接时触发此回调,代表真的连接成功
*/
$client->on('connect', function($client){
echo "connect successful..." . PHP_EOL;
$client->send('I have connected to server...' . PHP_EOL);
});
/**
* 接收到服务端信息时触发,服务端也是异步发信息的
*/
$client->on('receive', function($client, $data){
echo "receive data from server: " . $data . PHP_EOL;
$client->close();// 触发onClose回调
});
/**
* 客户端或服务端关闭了此连接时触发
*/
$client->on('close', function($client){
echo "closed my connect..." . PHP_EOL;
});
/**
* 过程出现错误时触发
*/
$client->on('error', function($client){
echo "client error: " . $client->errCode . PHP_EOL;
});
$client->connect('127.0.0.1', 9001, 0.1);
echo "我先输出,表示的确是异步执行的..." . PHP_EOL;
Swoole客户端
连接类型:通过设置参数可实现tcp,udp,socket客户端。
是否同步:分为同步阻塞的和异步非阻塞的;客户端默认是 TCP+同步阻塞 模式
可以在实例化的时候设置,也可以在连接的时候设置,还可以在设置运行时参数。
TCP用在消息通讯,硬件通讯。
同步模式:
1、connect方法会阻塞,直到连接成功并返回true。如果连接失败,会返回false。
2、通过recv()函数接受数据,如果没有接受到数据,会报错。
异步模式:
1、异步客户端的话每一步几乎都不能立即返回结果,所以基本都是注册回调事件来接受结果,这一点和服务端一样。
2、connect()方法会立即返回true,但实际上连接并未建立,所以不能在connect后面使用send,并且通过isConnect()
判断也是false,当连接成功后,系统会自动回调onConnect。这时才可以使用send向服务器发送数据。
3、connect失败后如果希望重连一次,必须先进行close关闭旧的socket,否则会返回EINPROCESS错误,因为当前的
socket正在连接服务器,客户端并不知道是否连接成功,所以无法再次执行connect。调用close会关闭当前的socket,
底层重新创建新的socket来进行连接。
4、在receive回调中接受数据。
5、需要注意,必须先注册(connect, receive, close, error)回调再使用connect()函数连接,否则会报错。
命令
ps -ef |grep php 查看进程
netstat -lntp 查看端口监听
pkill -f tcp_server.php 批量杀掉进程