当尝试写入客户端时,消息被缓冲,在某些情况下,它根本就没有被写入.
当前状态:
当我远程登录到服务器时,可以按预期方式打印“服务器就绪:”消息.
当我发送随机数据(“关闭”除外)时,服务器的终端每秒都很好地显示进度,但客户端输出等待直到所有睡眠后,然后立即打印所有数据.
最重要的是,当发送“关闭”时,它只是等待强制性的第二个,然后在客户端没有任何写出的情况下关闭.
码:
// server.PHP
$loop = React\EventLoop\Factory::create();
$socket = new React\Socket\Server($loop);
$socket->on('connection', function ($conn)
{
$conn->write("Server ready:\n");
$conn->on('data', function ($data) use ($conn)
{
$data = trim($data);
if( $data == 'close')
{
$conn->write("Bye\n");
sleep(1);
$conn->close();
}
for ($i = 1; $i<5; $i++) {
$conn->write(". ");
echo '. ';
sleep(1);
}
$conn->write(".\n");
echo ".\n";
$conn->write("You said \"".$data."\"\n");
});
});
$socket->listen(1337, '127.0.0.1');
$loop->run();
解决方法:
您遇到的问题是因为您忘记了驱动ReactPHP的事件循环.我最近在构建服务器时遇到了这个问题,在遵循代码后,我发现了两件可以帮助你解决问题的事情.
>如果在写入后关闭连接,它只会在写入之前关闭连接.解决这个问题可以帮助你解决下一个问题…正确的要求写一些东西到客户端,然后关闭连接称为$conn-> end(‘msg’);如果你遵循这个代码链,行为就会变得清晰;首先,它基本上写入连接,就像你运行$conn-> write(‘msg’);但是它为全流失事件注册了一个新的事件处理程序,这个处理程序简单地调用$conn-> close();;只有在写缓冲区完全清空时才会调度全流失事件.所以你可以看到使用end,只需在关闭连接之前等待写入.
只有在写入流后才会调度漏极和全漏极.写缓冲区完全为空时发生全漏.写缓冲区清空后通过其softLimit调度drain,默认值为2048字节.
>你的写入没有通过的原因是因为$conn-> write(‘msg’)只将字符串添加到写缓冲区;它实际上并没有写.事件循环需要在给定时间写入之前运行.你对sleep()的使用是不正确的,因为这会阻止该行的调用.在反应中,您不希望阻止任何代码执行.如果您完成了一项任务,那么让您的函数返回,代码执行返回到反应主事件循环.如果您希望在某些时间间隔内运行,或者只是在循环的下一次迭代中运行,您可以使用$loop-> addTimer($seconds,$callback),$loop为主事件循环安排回调 – > addPeriodicTimer($seconds,$callback),$loop-> nextTick($callback)或$loop-> futureTick($callback)
最终,这是因为你在编程而没有承认我们仍然处于阻塞线程中.你的代码阻塞,阻止整个反应事件循环,反过来阻止所有反应为你做的事情.将处理时间放回循环以确保它可以执行排队的读/写操作.您只需要在循环的迭代中进行写缓冲区开始清空(取决于缓冲区的大小,它可能会或可能不会全部写出来)
如果您的目标只是修复连接关闭位,请将您的通话切换为$conn-> end(‘msg’)而不是写 – >关.但是我相信你打印圆点的另一个循环也不会像我认为你期望/希望它的工作方式那样.因为它的目的不是很明确,如果你能告诉我你的目标是什么,我也可以帮助你重组这一步骤.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。