Утечки памяти при использовании 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>