寒冰
  • 1
  • 新人请关照

新版本的swoole,Client异步事件被移除了,协程Client该如何使用

各位高手,根据官方的建议是用协程Client,替代原来的Client异步事件。
官方的使用文档如下

use Swoole;
$client = new Coroutine\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, 0.5))
{
    exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");
echo $client->recv();
$client->close();

这种用法只适合服务端能立马返回数据的场景。
假如服务端是不规律(时间无法确定)的向client发送数据,client需要被动等待服务端的数据,就只能用无限循环吗?如下

use Swoole;
$client = new Coroutine\Client(SWOOLE_SOCK_TCP);
if (!$client->connect('127.0.0.1', 9501, 0.5))
{
    exit("connect failed. Error: {$client->errCode}\n");
}
$client->send("hello world\n");
while(1){//无限循环,等待服务端的数据
echo $client->recv();
}

这种用法会不会浪费资源,因为很多时候可能服务端没有发送数据,这样client就是在做无用的循环,有没有其他办法。

阅读 333
评论 1月13日提问
    2 个回答

    这只不过是没有包装一个和以前一样的API而已,如果给client增加一个方法,看起来和以前差不多了

    class Client
    {
        ..........
        
        public function message($func) {
            while(1) {
                $data = $this->recv();
                if ($data !== '') {
                    $func($data)
                } 
            }
        }
    }
    
    $client->send("hello world\n");
    $client->message(function($data){
        echo $data;
    }); 
    
    这种用法只适合服务端能立马返回数据的场景。

    这和服务器立马返回数据没有关系,这是你的需求问题,你只需要一条数据,那recv一次,你需要服务器返回的所有数据,你也不知道服务器什么时候回发数据,那就循环一直recv

    其实基于事件驱动更符合人类生活,比如电话响->就接电话,门铃响->就开门。

    事件循环解决的不是 电话响-接电话 这种逻辑流程问题,它解决的是 通知你电话响没响 的问题,事件循环往往是一个顶层的 while(1),轮训各种事件,触发了就执行回调

    评论 赞赏 1月14日