接着上个(https://blog.csdn.net/weixin_44183558/article/details/121692189)继续
这里我们需要先了解一个函数stream_set_blocking(resource $stream
, bool $enable
);
stream
资源流。
enable
如果 enable
为 false
,资源流将会被转换为非阻塞模式;如果是 true
,资源流将会被转换为阻塞模式。 该参数的设置将会影响到像 fgets() 和 fread() 这样的函数从资源流里读取数据。 在非阻塞模式下,调用 fgets() 总是会立即返回;而在阻塞模式下,将会一直等到从资源流里面获取到数据才能返回。
创建下面蓝色框的文件和文件夹
WorkerBase.php和Worker.php的内容不变,和第一个一样
server.php内容
<?php
require_once __DIR__."/../../vendor/autoload.php";
use Ztms\NonBlocking\Worker;
$server = new Worker('0.0.0.0', 9500);
$server->on('connect', function($server, $client){
echo "1我们连接成功啦"."\n";
});
$server->on('receive', function(Worker $server, $client, $data){
//接受客户端消息
echo '2'.$data."\n";
//服务端发送给客户端
sleep(5);
$server->send($client, "3滚,你这个渣男,你对别人也是这么说的吧");
$server->close($client);
});
$server->on('close', function($server, $client){
echo "4说完就断开了连接"."\n";
});
$server->start();
client.php内容
<?php
require_once __DIR__."/../../vendor/autoload.php";
// 连接服务端
$fp = stream_socket_client("tcp://192.168.0.100:9500");
// $fp = stream_socket_client("tcp://192.168.12.210:9500");
//第二个参数我们设置为false(非阻塞)
stream_set_blocking($fp, false);
//给服务端发送内容
fwrite($fp, "一直有句话想对你说 做我的女朋友吧!");
//服务端发送过来的内容
echo '第一次读取服务端的消息->'.fread($fp, 65535)."\n";
//这里不需要等到服务端发送过的内容就可以执行,这里就体现了非阻塞,我们可以在等待服务端发送过来的内容是去干别的事情
echo '等待的时候抽根华子或者刷刷抖音'."\n";
//这里我们隔一会就去问服务端,好了吗好了吗
while (!feof($fp)) {
sleep(1);
echo '第n+1次读取服务端的消息->'.fread($fp, 65535)."\n";
}
在客户端第一次读取服务端的消息时(其实就是读服务端写给socket的内容),客户端并没有接收到任何东西,因为在服务端我们设置了sleep5秒钟再发送消息(给socket)写内容,这里因为我们使用文章头部的函数(为了方便测试我直接用在了客户端),第二个参数设置成了false,我们可以在等待服务端发送消息回来的时候可以去做其他事情(这里就是和阻塞的区别,阻塞时一定要等到服务端回应才能去做别的事情),每隔一会我们就去问一下服务端,知道服务端返回消息了才断开连接;
举例:
连接成功之后,
客户端:一直有句话想对你说 做我的女朋友吧!
服务端:犹豫不决(这里是服务端的心理活动,并不是发送消息给客户端)
(阻塞)客户端:傻傻站在原地等待(啥事都不能做)
(非阻塞)客户端:我先抽根华子,刷刷抖音看看美女,每隔一会我就来问下你(可以做一些其他事情)
服务端:滚,你这个渣男,你对别人也是这么说的吧
然后就断开了连接