Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah Saya Boleh Mendapatkan Saiz Fail Masa Nyata Muat Naik Terikat Pelayan?

Bagaimanakah Saya Boleh Mendapatkan Saiz Fail Masa Nyata Muat Naik Terikat Pelayan?

Susan Sarandon
Susan Sarandonasal
2024-10-20 22:02:02208semak imbas

How Can I Get the Real-Time File Size of a Server-Bound Upload?

Soalan:

Dapatkan saiz fail masa nyata bagi fail yang dimuat naik semasa ia ditulis ke pelayan tanpa menyekat kedua-dua pelayan dan klien.

Konteks:

Progres muat naik fail dalam penyemak imbas pelanggan semasa menulis ke pelayan menggunakan permintaan POST fetch() dengan Fail atau badan Blob.

Keperluan:

Paparkan saiz fail sebagai teks/strim-acara semasa ia ditulis ke sistem fail pelayan. Berhenti apabila semua bait yang disediakan sebagai parameter rentetan pertanyaan semasa muat naik fail telah ditulis. Saiz fail pada masa ini diambil daripada skrip berasingan, yang dipanggil selepas fail telah ditulis ke pelayan.

Pelaksanaan:

Pada mulanya cuba menggunakan PHP tetapi menghadapi ralat disebabkan HTTP_LAST_EVENT_ID yang tidak ditentukan dan saiz fail yang salah dilaporkan. Juga bereksperimen dengan pendekatan dan bahasa yang berbeza seperti bash, c, nodejs dan python.

Penyelesaian:

  1. Kosongkan cache statistik fail untuk mendapatkan fail masa nyata saiz:
<code class="php">clearstatcache(true, $upload);
$data = filesize($upload);</code>
  1. Strim.php yang diubah suai dengan pengendalian ralat dan menggunakan usleep untuk prestasi yang lebih baik:
<code class="php">// Check if the header's been sent to avoid `PHP Notice:  Undefined index: HTTP_LAST_EVENT_ID in stream.php on line `
// php 7+
//$lastId = $_SERVER["HTTP_LAST_EVENT_ID"] ?? 0;
// php < 7
$lastId = isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? intval($_SERVER["HTTP_LAST_EVENT_ID"]) : 0;

$upload = $_GET["filename"];
$data = 0;
// if file already exists, its initial size can be bigger than the new one, so we need to ignore it
$wasLess = $lastId != 0;
while ($data < $_GET["filesize"] || !$wasLess) {
    // system calls are expensive and are being cached with assumption that in most cases file stats do not change often
    // so we clear cache to get most up to date data
    clearstatcache(true, $upload);
    $data = filesize($upload);
    $wasLess |= $data < $_GET["filesize"];
    // don't send stale filesize
    if ($wasLess) {
        sendMessage($lastId, $data);
        $lastId++;
    }
    // not necessary here, though without thousands of `message` events will be dispatched
    //sleep(1);
    // millions on poor connection and large files. 1 second might be too much, but 50 messages a second must be okay
    usleep(20000);
}</code>
  1. Sertakan fileId dan fileSize sebagai sebahagian daripada permintaan POST dan tambahkan storan dalam memori menggunakan redis atau memcache untuk menyimpan metadata fail.
  2. Gunakan EventSource dalam JavaScript sisi klien:
<code class="javascript">const [fileId, request, source] = [
    Math.random().toString(36).substr(2),
    new Request(`${url}?fileId=${fileId}&amp;size=${filesize}`, {
        method: "POST",
        headers: headers,
        body: file
    }),
    new EventSource(`${stream}?fileId=${fileId}`)
];</code>
  1. Sesuaikan setUnique dan fungsi kemas kiniProgress berdasarkan mekanisme storan pilihan anda:
<code class="php">function setUnique(string $id, int $size) {
    // implement with your storage of choice
}

function updateProgress(string $id, int $processed) {
    // implement with your storage of choice
}</code>
  1. Dapatkan kemajuan daripada storan:
<code class="php">list($progress, $size) = getProgress($_GET["fileId"]);</code>

Nota Penting:

  • Penyelesaian yang disediakan mengutamakan fungsi berbanding keselamatan dan tidak disyorkan untuk kegunaan pengeluaran tanpa melaksanakan langkah keselamatan tambahan.
  • Bilangan sambungan terbuka mungkin perlu dilaraskan berdasarkan konfigurasi pelayan dan penggunaan sumber.
  • Daripada EventSource, menggunakan tinjauan pendapat boleh dianggap untuk mengurangkan bilangan sambungan terbuka, tetapi ia mungkin memberi kesan kepada responsif.
  • Masa tidur optimum dalam tidur () mungkin berbeza-beza bergantung pada kekerapan kemas kini yang diingini dan pertukaran prestasi.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mendapatkan Saiz Fail Masa Nyata Muat Naik Terikat Pelayan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn