Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Measure network bandwith in PHP

I am transferring large files (1gb+) from Dropbox to YouTube and want to inform the user how much time the transaction will presumably take. Is there any means to measure the network traffic in PHP?

I did find solutions for the linux shell (How to measure network performance (how to benchmark network protocol)) but not for PHP.

In addition to inform the user I want to check the guaranteed bandwidth (100 mbit/s) as I ran into network problems (bandwidth too low) a couple of times.

like image 575
Jan Avatar asked Jul 29 '15 06:07

Jan


2 Answers

I don't really know if you are trying to do an estimate or give a "live" feedback to the user.

If you are doing an estimated I think you can just go the OS route and do an "exec" (like @kost suggested) that will tell you the current load. No need to overthink it!

So, lets go to the live solution :)!

First of all take a look into ReactPHP (http://reactphp.org/) and then into the streams implementation of ReactPHP (https://github.com/reactphp/stream).

The idea would be to create a readable stream where you would be reading chunks of data from your source (DropBox?) and as you do, you will keep calculating the remaining time and writing it to and writable stream that could be a Web Socket for example.

Here is a little example reading from a big local file, calculating the % and writing to the stdoud:

<?php
require 'vendor/autoload.php';
$loop = React\EventLoop\Factory::create();
$read = new \React\Stream\Stream(fopen('hugefile.txt', 'r+'), $loop);
$fileStats = fstat($read->stream);
$totalSize = $fileStats['size'];
$chunkSize = $totalSize/100;
$currChunk = 1;
$write = new \React\Stream\Stream(fopen('php://stdout', 'w+'), $loop);
$totalReadBytes = 0;
$read->on('data', function ($data, $read) use ($write, &$totalReadBytes, $totalSize, &$currChunk, $chunkSize) {
  $totalReadBytes += strlen($data);
  if($totalReadBytes > ($chunkSize * $currChunk)){
    $currChunk = ceil(($totalReadBytes/$totalSize)*100);
    $write->write(sprintf('%010d',$totalReadBytes).'/'.sprintf('%010d',$totalSize).' - '.$currChunk.'%'.PHP_EOL);
  }
});
$loop->run();

Note that all you would need to do is change the input of the readable stream and the output of the writabble stream.

Also you could pipe the readable stream to a file (that you would later upload to youtube) or even better if the youtube allows it, just pipe it to youtube (that would be awesome :D).

EDIT adding some of my comments for visibility:

since ReactPHP is basically a shameless copy of NodeJS, the concept of the code and idea I posted could be easily be implemented in NodeJS (the code should even look alike). With this I'm not trying to say ReactPHP is worse or better :) I just think you can achieve the same result with Node and their documentation is WAY better, with ReactPHP you will find yourself digging into the code to figure stuff out.

I think the core of ReactPHP is stable enough but I understand your concern. That being said, If I where you I would definitely try using NodeJS. If you know the basics of JS it should be practically the same learning curve you would have with ReactPHP (if not less, since there is more resources out there for Node than ReactPHP).

like image 177
Jhuliano Moreno Avatar answered Nov 12 '22 06:11

Jhuliano Moreno


Create a linux bash-script and run it from PHP using exec or system function.

like image 2
kost Avatar answered Nov 12 '22 06:11

kost