mOr*_*off 3 php sockets reactphp
当尝试写入客户端时,消息被缓冲,在某些情况下,它根本就没有被写入.
当前状态:
当我远程登录到服务器时,Server Ready:
消息很容易按预期打印.
当我发送随机数据("关闭"除外)时,服务器的终端每秒都很好地显示进度,但客户端输出等待直到所有睡眠后,然后立即打印所有数据.
最重要的是,当发送"关闭"时,它只是等待强制性的第二个,然后在客户端没有任何写出的情况下关闭.
目标:
我的主要目标是在关闭连接之前将快速消息写入客户端.
码:
// 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();
Run Code Online (Sandbox Code Playgroud)
摘要:
为什么我不能在关闭之前把任何东西写到客户端?
您遇到的问题是因为您忘记了驱动ReactPHP的事件循环.我最近在构建服务器时遇到了这个问题,在遵循代码后,我发现了两件可以帮助你解决问题的事情.
$conn->end('msg');
如果你遵循这个代码链,行为变得清晰; 首先,它基本上写入连接,就像你运行,$conn->write('msg');
但然后它为事件注册一个新的事件处理程序full-drain
,这个处理程序简单调用$conn->close();
; full-drain
只有在写缓冲区完全清空时才会调度该事件.所以你可以看到使用end,只需在关闭连接之前等待写入.该drain
和full-drain
写入数据流之后,仅调度.full-drain
写缓冲区完全为空时发生.drain
在写入缓冲区清空之后调度softLimit
,默认情况下为2048字节.
$conn->write('msg')
只将字符串添加到写缓冲区; 它实际上并没有写.事件循环需要在给定时间写入之前运行.您对sleep()
反应的使用不正确,因为这会阻止该行的呼叫.在反应中,您不希望阻止任何代码执行.如果您完成了一项任务,那么让您的函数返回,代码执行返回到反应主事件循环.如果你想拥有的东西在特定的时间间隔运行,或只是在循环的下一次迭代中,你可以安排主事件循环回调与使用$loop->addTimer($seconds, $callback)
,$loop->addPeriodicTimer($seconds, $callback)
,$loop->nextTick($callback)
或$loop->futureTick($callback)
最终,这是因为你在编程而没有承认我们仍然处于阻塞线程中.你的代码阻塞,阻止整个反应事件循环,反过来阻止所有反应为你做的事情.将处理时间放回循环以确保它可以执行排队的读/写操作.您只需要在循环的迭代中进行写缓冲区开始清空(取决于缓冲区的大小,它可能会或可能不会全部写出来)
如果您的目标只是修复连接关闭位,请将您的呼叫切换到$conn->end('msg')
而不是写 - >关闭.但是我相信你打印圆点的另一个循环也不会像我认为你期望/希望它的工作方式那样.因为它的目的不是很明确,如果你能告诉我你的目标是什么,我也可以帮助你重组这一步骤.
归档时间: |
|
查看次数: |
1605 次 |
最近记录: |