كيفية الحد من سرعة الاستجابة الصادرة من البرنامج النصي PHP؟

StackOverflow https://stackoverflow.com/questions/3110725

سؤال

كيفية الحد من سرعة الاستجابة الصادرة من البرنامج النصي PHP؟ لذلك لديّ بيانات نصي لإنشاء نصوص في اتصال محافظ. إنه يفتح الملف ويقرأه. كيفية الحد من السرعة الصادرة

(الآن لدي مثل هذا الرمز)

if(isset($_GET[FILE]))
 {
  $fileName = $_GET[FILE];
  $file =  $fileName;

  if (!file_exists($file))
  {
   print('<b>ERROR:</b> php could not find (' . $fileName . ') please check your settings.'); 
   exit();
  }
  if(file_exists($file))
  {
   # stay clean
   @ob_end_clean();
   @set_time_limit(0);

   # keep binary data safe
   set_magic_quotes_runtime(0);

   $fh = fopen($file, 'rb') or die ('<b>ERROR:</b> php could not open (' . $fileName . ')');
   # content headers
   header("Content-Type: video/x-flv"); 

   # output file
   while(!feof($fh)) 
   {
     # output file without bandwidth limiting
     print(fread($fh, filesize($file))); 
   } 
  } 
 }

إذن ما الذي يجب أن أفعله للحد من سرعة الاستجابة (على سبيل المثال 50 كيلو بايت/ثانية)

هل كانت مفيدة؟

المحلول

قم بتغيير إخراج الملف الخاص بك ليكون متداخلاً بدلاً من إخراج الملف بأكمله في واحد.

# output file
while(!feof($fh)) 
{
    # output file without bandwidth limiting
    print(fread($fh, 51200)); # 51200 bytes = 50 kB
    sleep(1);
}

سيؤدي ذلك إلى إخراج 50 كيلو بايت ثم انتظر ثانية واحدة حتى يتم إخراج الملف بأكمله. يجب أن تقطع النطاق الترددي إلى حوالي 50 كيلو بايت/ثانية.

على الرغم من أن هذا ممكن داخل PHP ، إلا أنني سأقوم استخدم خادم الويب الخاص بك للتحكم في الاختناق.

نصائح أخرى

لن أستخدم PHP للحد من عرض النطاق الترددي:

لأباش: عرض النطاق الترددي MOD V0.7 (إرشادي - محدد النطاق الترددي لـ Apache2)

ل nginx: http://wiki.nginx.org/nginxhttpcoremodule#limit_rate

لـ Lighttpd: http://redmine.lighttpd.net/projects/lighttpd/wiki/docs:trafficshaping حتى أن هذا يسمح لك بتكوين السرعة لكل اتصال في PHP

يمكنك قراءة N Bytes ثم استخدام استخدام Sleep (1) للانتظار لثانية واحدة ، كما هو مقترح هنا.

أعتقد أن طريقة "Ben S" و "Igorw" خاطئة لأنها تعني عرض النطاق الترددي غير المحدود وهو افتراض خاطئ. في الأساس نص يقول

while(!feof($fh)) {
   print(fread($fh, $chunk_size));
   sleep(1);
}

سوف توقف لثانية واحدة بعد إخراج $ chunk_size عدد البايتات بغض النظر عن المدة التي استغرقتها. على سبيل المثال ، إذا كانت الإنتاجية الحالية الخاصة بك 100 كيلو بايت وتريد البث بسرعة 250 كيلو بايت ، فسيستغرق البرنامج النصي أعلاه 2.5 ثانية للقيام بالطباعة () ثم انتظر ثانية أخرى ، مما يدفع النطاق الترددي الحقيقي إلى حوالي 70 كيلو بايت.

يجب أن يقيس الحل إما الوقت الذي استغرقه PHP لإكمال print () statemnt أو استخدام المخزن المؤقت والاتصال بالتدفق مع كل fread (). النهج الأول سيكون:

list($usec, $sec) = explode(' ', microtime());
$time_start = ((float)$usec + (float)$sec);
# output packet
print(fread($fh, $packet_size));
# get end time
list($usec, $sec) = explode(' ', microtime());
$time_stop = ((float)$usec + (float)$sec);
# wait if output is slower than $packet_interval
$time_difference = $time_stop - $time_start;
if($time_difference < (float)$packet_interval) {
    usleep((float)$packet_interval*1000000-(float)$time_difference*1000000);
}

في حين أن الثاني سيكون شيئًا مثل:

ob_start();
while(!feof($fh)) {
       print(fread($fh, $chunk_size));
       flush();
       ob_flush();
       sleep(1);
    }

يمكنك إرفاق أ bandwidth-throttle/bandwidth-throttle إلى دفق:

use bandwidthThrottle\BandwidthThrottle;

$in  = fopen(__DIR__ . "/resources/video.mpg", "r");
$out = fopen("php://output", "w");

$throttle = new BandwidthThrottle();
$throttle->setRate(500, BandwidthThrottle::KIBIBYTES); // Set limit to 500KiB/s
$throttle->throttle($out);

stream_copy_to_stream($in, $out);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top