Утечки памяти при использовании PHP-скрипта для открытия и закрытия сокета из Asterisk Manager

Я использую звездочку ami, чтобы открыть сокет и отправить команды на сервер звездочек для конкретных задач. Насколько я могу сказать, сокет открыт, команда отправлена, сокет затем закрыт. Тем не менее, мое использование памяти на машине звездочки немного увеличивается со временем, пока не дойдет до того, что мне придется перезапустить службу httpd. Это не так много кода, но я новичок в php, поэтому я не уверен, что не так или я должен искать в другом месте.

<?php
echo $sipexten = $_REQUEST["sipexten"];
echo $xferext = $_REQUEST["xferext"];

$wrets = "";
$amiusername = 'XXX';
$amisecret   = 'XXX';
$socket = '';       

//MAIN PROCESS       
//quit if any parameters are missing
if ($sipexten == '' || $xferext == ''){
    exit('not enough parameters');   //stop further processing for not enough     parameters
}

ob_implicit_flush(true);
$socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);    
$wrets = fread($socket,30);
fputs($socket, "Action: Login\r\n");
fputs($socket, "UserName: $amiusername\r\n");
fputs($socket, "Events: off\r\n");
fputs($socket, "Secret: $amisecret\r\n\r\n");
fputs($socket, "Action: CoreShowChannels\r\n\r\n");
fputs($socket, "Action: Logoff\r\n\r\n");        
while (!feof($socket)) {
    $wrets .= fread($socket,8192 );
}
fclose($socket);   

$sipexten = "Channel: SIP/$sipexten";
$channelVal = strpos($wrets,$sipexten);
if ($channelVal){
    $channel=trim(substr($wrets,$channelVal+9,strpos(substr($wrets,$channelVal),"UniqueID:")-9)    );
}


ob_implicit_flush(true);
$socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);    
$wrets = fread($socket,30);
fputs($socket, "Action: Login\r\n");
fputs($socket, "UserName: $amiusername\r\n");
fputs($socket, "Events: off\r\n");
fputs($socket, "Secret: $amisecret\r\n\r\n");
fputs($socket, "Action: Atxfer\r\n");
fputs($socket, "Channel: $channel\r\n");
fputs($socket, "Exten: $xferext\r\n");
fputs($socket, "Priority: 1\r\n\r\n");
fputs($socket, "Action: Logoff\r\n\r\n");        
while (!feof($socket)) {
    $wrets .= fread($socket,8192 );
}
fclose($socket); 
echo "<br />";         
echo $wrets;
?>

Вот как выглядит мой другой скрипт:

<?php

$sipexten = $_REQUEST["sipexten"];

$command = $_REQUEST["command"];

$isgood = $_REQUEST["isgood"]; 

$subfolder = $_REQUEST["subfolder"];

$srcname = $_REQUEST["srcname"];

$dstname = $_REQUEST["dstname"];


$wrets = "";
$amiusername = 'XXX';
$amisecret   = 'XXX';
$sipchannel = '';

$audiofolder = '/var/lib/asterisk/sounds/customaudio2play/';
$badfolder = 'bad';
$goodfolder = 'good';
$recordingformat = 'gsm'; 
$socket = '';        


if ($command == 'start'){  
    if ($sipexten == '' || $subfolder == '' || $srcname ==''){
        exit('not enough parameters');   //stop further processing for not enough parameters
    }
    //Check if SIP/sipexten is having a call. If yes, proceed.

    $sipchannel = amigetchannel();

    if ($sipchannel != '') {

        //AMI LOGIN


        // don't buffer output... flush it immediately
        ob_implicit_flush(true);
        $socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);    
        $wrets = fread($socket,30);
        //AMI Login
        fputs($socket, "Action: Login\r\n");
        fputs($socket, "UserName: $amiusername\r\n");
        fputs($socket, "Events: off\r\n");
        fputs($socket, "Secret: $amisecret\r\n\r\n");
        fputs($socket, "Action: Monitor\r\n");
        fputs($socket, "Channel: $sipchannel\r\n");
        fputs($socket, "File: $audiofolder/$subfolder/$srcname\r\n");
        fputs($socket, "Format: $recordingformat\r\n");
        fputs($socket, "Mix: 1\r\n\r\n");

        //LOG OFF AMI
        fputs($socket, "Action: Logoff\r\n\r\n"); 
        while (!feof($socket)) {
            $wrets .= fread($socket,8192 );
        }
        fclose($socket);  
        echo $wrets;
        echo ('start executed');
    } else {
        //No channel found
        echo ('No active channel');
    }       //$sipchannel != '';    
    //DONE

} elseif ($command == 'stop'){
    if ($sipexten == ''){
        exit('not enough parameters');   //stop further processing for not enough parameters
    }

    //Get current channel of $sipexten
    $sipchannel = amigetchannel();

    if ($sipchannel != '') {


        //AMI LOGIN
        // don't buffer output... flush it immediately
        ob_implicit_flush(true);
        $socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);    
        $wrets = fread($socket,30);
        //AMI Login
        fputs($socket, "Action: Login\r\n");
        fputs($socket, "UserName: $amiusername\r\n");
        fputs($socket, "Events: off\r\n");
        fputs($socket, "Secret: $amisecret\r\n\r\n");
        fputs($socket, "Action: StopMonitor\r\n");
        fputs($socket, "Channel: $sipchannel\r\n\r\n");

        //LOG OFF AMI
        fputs($socket, "Action: Logoff\r\n\r\n"); 
        while (!feof($socket)) {
            $wrets .= fread($socket,8192 );
        }
        fclose($socket);  
        echo $wrets;

    }
    echo ('stop executed');
} elseif ($command=='showchannels') {

    echo ('</br> sip channel: ' . amigetchannel());

}

echo ('</br>End of file');


function amigetchannel(){


    global $sipexten, $amiusername, $amisecret;

    // don't buffer output... flush it immediately
    ob_implicit_flush(true);
    $socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);    
    $wrets = fread($socket,30);
    //AMI Login
    fputs($socket, "Action: Login\r\n");
    fputs($socket, "UserName: $amiusername\r\n");
    fputs($socket, "Events: off\r\n");
    fputs($socket, "Secret: $amisecret\r\n\r\n");

    fputs($socket, "Action: CoreShowChannels\r\n\r\n");

    //LOG OFF AMI
    fputs($socket, "Action: Logoff\r\n\r\n"); 
    while (!feof($socket)) {
        $wrets .= fread($socket,8192 );
    }
    fclose($socket);  

    $needle = "Channel: SIP/" . $sipexten;
    $channelVal = strpos($wrets,$needle);

    if ($channelVal){
$sipchannel=trim(substr($wrets,$channelVal+9,strpos(substr($wrets,$channelVal),"UniqueID:")-9));
            }

}


?>

1 ответ

Используйте утилиту top или ps, чтобы проверить, какой процесс использует память, после чего отлаживайте свой код на предмет утечек памяти.

Если apache использует память, проверьте ваш httpd.conf, есть параметр "MaxRequestsPerChild", который можно использовать для перезапуска ошибочного потока.

<IfModule worker.c>
StartServers         2
MaxClients         150
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25
MaxRequestsPerChild  0
</IfModule>
Другие вопросы по тегам