Comment puis-je surveiller en temps réel la progression du téléchargement de fichiers sans bloquer le serveur ou le client ?

Barbara Streisand
Libérer: 2024-10-20 22:03:30
original
357 Les gens l'ont consulté

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

Comment suivre la progression d'un téléchargement de fichier en temps réel sans bloquer le serveur ou le client ?

Contexte :
Lorsqu'un le téléchargement du fichier se produit, la progression du fichier en cours d'écriture sur le serveur peut être suivie. Cela peut être fait sans bloquer le serveur ou le client, ce qui permet une expérience utilisateur fluide et efficace.

Problème :
L'implémentation actuelle définit l'objet File comme corps d'une récupération. demande. Cependant, pour suivre la progression en temps réel, une approche différente est nécessaire.

Exigence :
Afficher la taille du fichier en cours d'écriture sur le serveur sous forme de texte/événement -flux. Le processus doit continuer jusqu'à ce que tous les octets fournis en tant que paramètre de chaîne de requête aient été écrits.

Solution :

Implémentation PHP :

<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();
}
Copier après la connexion

Implémentation JavaScript :

<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>
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!