Home  >  Article  >  Backend Development  >  How Can I Real-Time Monitor File Upload Progress Without Blocking the Server or Client?

How Can I Real-Time Monitor File Upload Progress Without Blocking the Server or Client?

Barbara Streisand
Barbara StreisandOriginal
2024-10-20 22:03:30359browse

How Can I Real-Time Monitor File Upload Progress Without Blocking the Server or Client?

How to monitor the progress of a file upload in real time without blocking the server or client?

Background:
When a file upload occurs, the progress of the file being written to the server can be tracked. This can be done without blocking the server or client, allowing for a smooth and efficient user experience.

Problem:
The current implementation sets the File object as the body of a fetch request. However, to monitor the progress in real time, a different approach is needed.

Requirement:
Display the file size of the file being written to the server as a text/event-stream. The process should continue until all bytes provided as a query string parameter have been written.

Solution:

PHP Implementation:

<code class="php">// stream.php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");

$lastId = isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? intval($_SERVER["HTTP_LAST_EVENT_ID"]) : 0;
$upload = $_GET["filename"];
$data = 0;
// Ignore file size if it's already there
$wasLess = $lastId != 0;
while ($data < $_GET["filesize"] || !$wasLess) {
    clearstatcache(true, $upload);
    $data = filesize($upload);
    $wasLess |= $data < $_GET["filesize"];
    if ($wasLess) {
        sendMessage($lastId, $data);
        $lastId++;
    }
    usleep(20000);
}

function sendMessage($id, $data)
{
    echo "id: $id\n";
    echo "data: $data\n\n";
    ob_flush();
}

JavaScript Implementation:

<code class="javascript">const [url, stream, header] = ["data.php", "stream.php", "x-filename"];

input.addEventListener("change", (event) => {
  const [file] = input.files;
  const [{ size: filesize, name: filename }, headers, params] = [file, new Headers(), new URLSearchParams()];

  headers.append(header, filename);
  progress.value = 0;
  progress.max = filesize;
  const [request, source] = [
    new Request(url, { method: "POST", headers, body: file }),
    new EventSource(`${stream}?${params.toString()}`)
  ];

  source.addEventListener("message", (e) => {
    progress.value = e.data;
    // Close the source when the data equals the filesize
    if (e.data == filesize) {
      source.close();
    }
  });
  fetch(request);
});</code>

The above is the detailed content of How Can I Real-Time Monitor File Upload Progress Without Blocking the Server or Client?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn