如何在没有 PHP Pusher 的情况下制作实时进度条
Posted
技术标签:
【中文标题】如何在没有 PHP Pusher 的情况下制作实时进度条【英文标题】:How To Make Realtime Progressbar Without PHP Pusher 【发布时间】:2021-10-16 02:17:25 【问题描述】:我陷入了这个问题,关于在 php 上制作实时进度条(没有 php pusher)
假设我有 10 行数据,将被插入到数据库中。
现在如何发送进度条数据,同时插入数据库。
非常感谢您的回答。 谢谢。
下面是我的代码示例:
// script.js (client)
// This function executed when user submit form
function store()
// Listen Server Side Event
let event = new EventSource('controller/store')
event.addEventListener('message', response =>
// Then update progressbar
updateProgressbar(response.percent)
)
// Ajax to save data to database
$.ajax(
url: baseUrl + 'controller/store',
type: 'POST',
dataType: 'JSON',
data: $('#form').serializeArray(),
success: function(response)
console.log(response)
)
// Controller.php (server)
public function store()
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
$total_row = count($_POST['customer']);
for ($i = 0; $i < $total_row; $i++)
usleep(100000);
$this->db->insert('customers', $_POST['customer'][$i]);
$percent = ($i + 1) * (100 / $total_row);
echo "event: message\n";
echo 'data: "status": "loading", "percent": "' . $percent . '"';
echo "\n\n";
ob_end_flush();
flush();
if (connection_aborted()) break;
echo "event: message\n";
echo 'data: "status": "done", "percent": "' . $percent . '"';
echo "\n\n";
【问题讨论】:
我根本不知道“PHP Pusher”是什么,但是除了服务器服务器端语言之外,您已经使用三种可用于执行此操作的技术对其进行了标记。你能把重点放在更具体的事情上吗? @ChrisHaas 在这种情况下,我使用 php(服务器)和 javascript(客户端)。我尝试使用 AJAX 插入数据并使用服务器发送事件显示进度条。问题是:AJAX 需要 JSON 作为响应,同时 SSE 需要 Event-Stream 作为响应。 HTTP 只能接受 1 种类型的响应。 这仍然需要更多解释,您要解决的更大的问题。进度条是否返回到正在发送数据的客户端;还是给其他客户?它是否一次发送所有 10 行数据,但每一行都需要很长时间才能插入数据库?还是一次发送一行? AJAX 不需要 JSON,它只是一个常见的约定。是客户发起了这个过程,还是只是被告知了它?进度条是字面的,还是只是“2:10”或“20%”或类似的文本? 这取决于你,如果没有关于服务器端可用内容的更多信息,你可以执行定期 ajax 请求来检查给出状态的 php 页面,你必须找到方法来做到这一点服务的 php 页面收集状态信息以及如何使用其响应来更新您的客户端页面。如果您对 websocket 感兴趣,也可以使用 php 完成,但您必须设置一个“专用”服务器(当前服务器的不同进程)。用php我喜欢这个ghedipunk on github 【参考方案1】:Web 服务器和浏览器不会让它按照你想要的方式工作。
HTTP 标头包含内容长度,Web 服务器在将文档发送到客户端之前需要知道该长度。除非您已经确切知道文档正文的长度,否则服务器(通常)会等到 PHP 脚本退出后再向客户端发送任何信息。
ob_end_flush()
和flush()
不直接向客户端发送信息;将它发送到 Web 服务器,它仍然会缓存它,直到准备好发送整个文档。
而且,客户端的 AJAX 请求也会等到整个文档都被接收到之后再运行success
函数。
因此,您需要在服务器上设置一些东西来存储进度,以便您可以调用另一个脚本。
您的服务器端脚本应该发回一个随机令牌,然后是continue processing php after sending http response。
然后,您的客户端脚本将需要偶尔使用该令牌查询您的服务器,直到长期进程完成或失败。
您可以使用 WebSockets 更快地更新客户端,正如 Tuckbros 在 cmets 中提到的那样(我很欣赏提到我的服务器),但除非用户知道进程何时在几十毫秒内结束很重要,我建议继续使用普通的 Web-PHP 和 AJAX,因为 WebSockets 需要对 CLI-PHP 和 HTTP 的额外细微差别有所了解。
【讨论】:
以上是关于如何在没有 PHP Pusher 的情况下制作实时进度条的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 在没有 NPM 的情况下安装 echo 和 pusher js
如何在 pusher 的帮助下使用 websocket 从数据库中获取数据?
如何使用 PHP 绑定到 Pusher / Websocket 通道?
Pusher:在 App\Events\Event 的 testChannel 上没有回调