使用PHP脚本从Asterisk Manager打开和关闭套接字时内存泄漏


Memory leaks when using PHP script to open and close socket from Asterisk Manager

我使用星号ami打开一个套接字并向星号服务器发送命令以执行特定任务。据我所知,套接字是打开的,命令被发送,然后套接字被关闭。但是,随着时间的推移,我在asterisk机器上的内存使用量会略微增加,直到我不得不重新启动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));
            }
}

?>

使用top或ps实用程序检查哪个进程使用内存,然后调试您的代码以查找内存泄漏

如果apache使用内存,检查你的httpd.conf,有一个参数"MaxRequestsPerChild",可以用来重启有问题的线程。

<IfModule worker.c>
StartServers         2
MaxClients         150
MinSpareThreads     25
MaxSpareThreads     75
ThreadsPerChild     25
MaxRequestsPerChild  0
</IfModule>