CS 1.6 чтоли? Если да, намного проще на pawn написать сбор подобной статистики.
Это называется long polling, в
php он отсутствует.
-------------
По хорошему подобный функционал не реализовать, нужно писать демона, который будет принимать данную инфу и передавать её в другие скрипты и записывать в файл.
Тот код, что выше не безопасен и обязательно вызовет ошибку либо обрежет строку во время чтения, потому что не используется блокировка. Если осуществлять блокировку в этом случае, скрипт пишущий в файл будет ожидать своей очереди на запись, а другой скрипт на чтение.
Файлы очень медленная хренотень, лучше использовать fifo либо Shared Memory and IPC. Либо писать свой протокол синхронизации и передачи данных через shmop и сигналы pctl, скорость возростет до несколько гигабайт в секунду.
Вот пример не блокирующего чтения с применением эвентов (эмуляция полинга)
<?php
class SHMOP
{
private static $shmop_key;
private static $PIPES;
private static $process;
private static $header_size = 6;
private static $event_stdio;
private static $event_sigio;
private static $pid;
public static function init($type, $fullpath, $memory = null, &$base)
{
if($type === 'client')
{
if(!is_numeric($memory))
return false;
$descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"));
self::$process = proc_open('/usr/local/bin/php -f '.$fullpath, $descriptorspec, self::$PIPES);
if(!is_resource(self::$process))
return false;
if(!self::open($fullpath, 'c', 0644, $memory))
return false;
self::$event_stdio = event_new();
event_set(self::$event_stdio, self::$PIPES[1], EV_READ | EV_PERSIST, __CLASS__.'::stdio_command');
event_base_set(self::$event_stdio, $base);
event_add(self::$event_stdio);
self::$event_sigio = event_new();
event_set(self::$event_sigio, SIGIO, EV_SIGNAL | EV_PERSIST, "IO_signal");
event_base_set(self::$event_sigio, $base);
event_add(self::$event_sigio);
fwrite(self::$PIPES[0], 'parent_pid:'.posix_getpid()."\n");
return true;
}
else if($type === 'server')
{
if(!self::open($fullpath, 'w'))
return false;
self::$event_stdio = event_new();
event_set(self::$event_stdio, STDIN, EV_READ | EV_PERSIST, __CLASS__.'::stdio_command');
event_base_set(self::$event_stdio, $base);
event_add(self::$event_stdio);
self::$event_sigio = event_new();
event_set(self::$event_sigio, SIGIO, EV_SIGNAL | EV_PERSIST, "IO_signal");
event_base_set(self::$event_sigio, $base);
event_add(self::$event_sigio);
return true;
}
else
return false;
}
public static function send_signal()
{
posix_kill(self::$pid, SIGIO);
}
public static function stdio_command($fd, $events)
{
$com = trim(fgets($fd));
$com_arr = explode(':', $com);
switch($com_arr[0])
{
case 'child_pid':
self::$pid = $com_arr[1];
break;
case 'parent_pid':
self::$pid = $com_arr[1];
fwrite(STDOUT, 'child_pid:'.posix_getpid()."\n");
break;
}
}
public function destruct()
{
self::delete();
self::close();
}
public function close()
{
if(shmop_close(self::$shmop_key))
return true;
else
return false;
}
private function delete()
{
if(shmop_delete(self::$shmop_key))
return true;
else
return false;
}
private static function open($fullpath, $flags, $mode = 0, $block_size = 0)
{
$shmop_key = self::key($fullpath);
self::$shmop_key = shmop_open($shmop_key, $flags, $mode, $block_size);
if(!self::$shmop_key)
return false;
shmop_write(self::$shmop_key, "\0", 0);
return true;
}
public static function read()
{
$command = shmop_read(self::$shmop_key, 0, 1);
if($command === "\0")
return '';
$datasize = (int)shmop_read(self::$shmop_key, 1, self::$header_size);
$data = shmop_read(self::$shmop_key, self::$header_size+1, $datasize);
shmop_write(self::$shmop_key, "\0", 0);
return $data;
}
public static function canwrite()
{
if(shmop_read(self::$shmop_key, 0, 1) === "\0")
return true;
else
return false;
}
public static function write($data)
{
$command = shmop_read(self::$shmop_key, 0, 1);
if($command !== "\0")
return false;
$datasize = strlen($data);
if(strlen($datasize) < self::$header_size)
$datasize .= "\0";
shmop_write(self::$shmop_key, $datasize, 1);
shmop_write(self::$shmop_key, $data, self::$header_size+1);
shmop_write(self::$shmop_key, "\1", 0);
return true;
}
public static function feof()
{
if(shmop_read(self::$shmop_key, 0, 1) === "\2")
return true;
else
return false;
}
public static function sendeof()
{
$command = shmop_read(self::$shmop_key, 0, 1);
if($command !== "\0")
return false;
shmop_write(self::$shmop_key, "\2", 0);
return true;
}
public static function key($fullpath = __FILE__)
{
return -934083471;
}
}
?>
<?php
$GLOBALS['dps'] = 0;
$GLOBALS['start_timer'] = 0;
require_once('shmop3.class.php');
$base = event_base_new();
$event_timer = event_timer_new();
event_timer_set($event_timer, 'handler_timer', $event_timer);
event_base_set($event_timer, $base);
event_timer_add($event_timer, 1000000);
event_add($event_timer);
SHMOP::init('client', 'proc_server.php', 200000, $base);
$GLOBALS['file'] = fopen('out.avi', 'wb');
event_base_loop($base);
function IO_signal()
{
if(!SHMOP::feof())
{
$data = SHMOP::read();
$GLOBALS['dps'] += strlen($data);
if($data !== '')
{
fwrite($GLOBALS['file'], $data);
SHMOP::send_signal();
}
}
else
{
fclose($GLOBALS['file']);
echo "close file\n";
}
}
function handler_timer($res, $status, $timer)
{
if($GLOBALS['start_timer'] == 0)
{
$GLOBALS['start_timer'] = 1;
SHMOP::send_signal();
}
echo 'Data Per Sec: '.convert($GLOBALS['dps'])."\n";
$GLOBALS['dps'] = 0;
event_timer_add($timer, 1000000);
}
function convert($size)
{
$unit=array('b','kb','mb','gb','tb','pb');
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
}
?>
<?php
set_error_handler('my_error_handler');
function my_error_handler($no,$str,$file,$line)
{
file_put_contents('./err.log', $no.$str.$file.$line."\n", FILE_APPEND);
}
require_once('shmop3.class.php');
$GLOBALS['file'] = fopen('in.avi', 'rb');
$base = event_base_new();
SHMOP::init('server', 'proc_server.php', null, $base);
event_base_loop($base);
function IO_signal($fd, $events, $arg)
{
if(!feof($GLOBALS['file']))
{
if(SHMOP::canwrite())
{
SHMOP::write(fread($GLOBALS['file'], 165536));
SHMOP::send_signal();
}
}
else
{
if(SHMOP::sendeof())
SHMOP::send_signal();
fclose($GLOBALS['file']);
}
}
?>
Скорость порядка 2 гигабайт в сек. Если конечно юзать не файл, а из памяти писать.
Смысл в том, что reader может заниматься своими делами, а witer может читать данные в это время, как только блок был прочитан от отправляет сигнал о готовности и у ридера срабатывает евент на чтение и блок копируется уже не с диска, а из сегмента разделяемой памяти, что уменьшает латентность при чтении и не вызывает ступоров.
Данный класс пока сырой прототип, но я уже кое где его применил и работает отлично.