сокеты — socket_select AF_UNIX Переполнение стека

Моя ситуация немного смущает, но я постараюсь объяснить.

Я пишу функциональность OSS на PHP, южный интерфейс взаимодействует с узлами GPON, а северный интерфейс взаимодействует с SOAP для остальной части всей системы.

Сейчас я пишу интерфейс TL1 для связи с узлом HUAWEI U2000, который сообщает мне TL1 / SSH и SNMP с OLT.

Все 32 соединения TL1 управляются n2000, и я пишу сервер для обработки всего соединения. Я решил соединение TL1 / SSH, и оно работает нормально, но мне нужно написать сервер для управления всеми 32 соединениями, очередями, приоритетами и т. Д.

Один клиент (пришедший php-скрипт и, например, SOAP-запрос) может отправить массив команд на мой сервер, и сервер должен выполнить команды и отправить ответ.

Это может заблокировать сервер на время последнего ответа, но у меня есть 32 возможных соединения, поэтому я реализую один FRONTENDserver и 32 BACKENDserver. Один клиент записывает запрос в сокет AF_UNIX на FRONTEND, а сервер отправляет его на свободный BACKEND, прослушивает другой сокет AF_UNIX, чтобы перехватить ответ, и отправить ответ верхнему клиенту.

Все работает нормально но у меня проблема:

Я реализовал тест с 2-мя серверами BACKEND и поместил немного сна в режим имитации блокировки, а также 3 клиентских скрипта cl1.php cl2.php cl3.php с тем же кодом.

когда: cl1.php run -> BCKEND1 засыпать 10 сек; запустите cl2.php -> BCKEND2 и перейдите в режим сна на 10 секунд, а когда я запускаю cl3.php, FRONTEND говорит «все занято», пока не освободится один, все нормально … НО

если я запускаю cl1.php -> sleep, cl2.php -> sleep, но в другой вкладке я запускаю cl2.php СНОВА FRONEND не принимает вызов, он ждет, пока BKEND2 освободится, а затем принимает «другой» вызов cl2.php снова.

другая вещь, которая меня смущает гораздо больше, это то, что если я запускаю cl1.php, cl2.php И СЕЙЧАС cl1.php? f = foo (или любой другой), то ОНО работает нормально: говорит «все занято».

Это похоже на то, что если скрипт имеет одно и то же имя, функция socket_select не запускается до тех пор, пока другой экземпляр не будет закрыт.

это код резюме:

FTEND


echo "servidor FEND proxy tl1\n";//socket por el cual recibo REQUESTS from client
$socketPedidosFile = "/tmp/php_socket/pedidos.sock";
unlink($socketPedidosFile);

$serverPedidos = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_bind($serverPedidos, $socketPedidosFile);
chmod($socketPedidosFile, "0702");
socket_listen($serverPedidos);//socket por el cual escucho las RESPONSES de los conectores.
$socketRespuestasFile = "/tmp/php_socket/respuestas.sock";
unlink($socketRespuestasFile);

$serverRespuestas = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_bind($serverRespuestas, $socketRespuestasFile);
chmod($socketRespuestasFile, "0702");
socket_listen($serverRespuestas);$clientesPedidos = array($serverPedidos);
$clientesRespuestas = array($serverRespuestas);$conectoresHW = array();
$conectoresHW[] = array("ocupado" => "0", "id" => null, "sockFile" => "/tmp/php_socket/con0.sock" ,"cliente" => null);
$conectoresHW[] = array("ocupado" => "0", "id" => null, "sockFile" =>        "/tmp/php_socket/con1.sock" ,"cliente" => null);//listen both sides
while(true) {

$r1 = $clientesPedidos;
//escucho pedidosif(socket_select($r1, $w, $e, 0, 500) > 0) {

$client = socket_accept($serverPedidos);
$comando = trim(socket_read($client, 1000000, PHP_NORMAL_READ));
$n = "";
socket_getsockname($client,$n);
echo "FEND:recibí el comando: $comando $n \n\n";

//este cliente tengo que guardarlo para escribir la respuesta

//veo que conector está ocupado
if ($conectoresHW[0]["ocupado"] === "0") {
//mando ejecutar al conector 0

//lo ocupo
echo "ocupo conector 0\n\n";
$conectoresHW[0]["ocupado"] = "1";
$conectoresHW[0]["cliente"] = $client;//este cliente es el que voy a tener que escribir
$conectoresHW[0]["id"] = "0";
$comando0= "0-".$comando;

//abro el socket
$socket_file0 = $conectoresHW[0]["sockFile"];
$socketC0  = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_connect($socketC0, $socket_file0);

//envio
$buffer0 = $comando0."\n";
$cantidad0 = socket_write($socketC0, $buffer0, strlen($buffer0));
echo "mandé al BKEND $cantidad0 bytes por el conector 0\n\n";}elseif ($conectoresHW[1]["ocupado"] === "0"){
//mando ejecutar al conector 1
//lo ocupo
echo "ocupo conector 1\n\n";
$conectoresHW[1]["ocupado"] = "1";
$conectoresHW[1]["cliente"] = $client;//este cliente es el que voy a tener que escribir
$conectoresHW[1]["id"] = "1";
$comando1 = "1-".$comando;

//abro el socket
$socket_file1 = $conectoresHW[1]["sockFile"];
$socketC1  = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_connect($socketC1, $socket_file1);

//envio
$buffer1 = $comando1."\n";
$cantidad1 = socket_write($socketC1, $buffer1, strlen($buffer1));
echo "mandé al BKEND $cantidad1 bytes por el conector 1\n\n";

}else {

//no tengo conectores libres
$bufferEx = "todos los conectores ocupados\n\n";
echo $bufferEx;

socket_write($client, $bufferEx, strlen($bufferEx));

socket_close($client);

}//echo socket_write($client, "$salida\n", strlen("$salida\n"));
//socket_close($client);
}

$r2 = $clientesRespuestas;if(socket_select($r2, $w, $e, 0, 500) > 0) {

$client = socket_accept($serverRespuestas);

$respComando = trim(socket_read($client, 1000000, PHP_NORMAL_READ));

//veo a que id corresponde la respuesta
$foo = explode("-", $respComando);
$id = $foo[0];
$res = $foo[1];

echo "me llegó la respuesa: $respComando $id\n";

$clientEscribir = $conectoresHW[$id]["cliente"];
$buffer = $res."\n";

$cantidad = socket_write($clientEscribir, $buffer, strlen($buffer));
echo "escribi $cantidad bytes en el cliente $id\n";

socket_close($clientEscribir);
$conectoresHW[$id]["ocupado"] = "0";
echo "libero conector {$id}\n\n";
}

//flush();
}
socket_close($serverPedidos);
socket_close($serverRespuestas);

BCKEND:


//este es el conector 0, escucho ese socket
$socketEscucho = "/tmp/php_socket/con0.sock";
unlink($socketEscucho);
$serverEscucho = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_bind($serverEscucho, $socketEscucho);
chmod($socketEscucho, "0702");
socket_listen($serverEscucho);//para dar la respuesta escribo en este como cliente
$socketRespuestas = "/tmp/php_socket/respuestas.sock";$clients = array($serverEscucho);

while(true) {
$r = $clients;

if(socket_select($r, $w, $e, null) > 0) {

$client = socket_accept($serverEscucho);

$comando = trim(socket_read($client, 1000000, PHP_NORMAL_READ));
$foo = explode("-", $comando);
$id = $foo[0];
$com = $foo[1];

echo "BEND:recibí el comando: $comando\n";

sleep(25);//simulo la ejecutada

$salida = "$id-esta_es_la_salida{$id}_del_comando_$com\n";

//doy la respuesta
$clienteRespuestas = socket_create(AF_UNIX, SOCK_STREAM, 0);
socket_connect($clienteRespuestas, $socketRespuestas);socket_write($clienteRespuestas, $salida, strlen($salida));

socket_close($client);
socket_close($clienteRespuestas);
}
flush();
}socket_close($serverEscucho);

КЛИЕНТЫ cliX.php

echo "<pre>".time()."\n\n";

$socket_file = "/tmp/php_socket/pedidos.sock";

$socket = socket_create(AF_UNIX, SOCK_STREAM, 0);

socket_connect($socket, $socket_file);

//envio

$buffer = "comando_entrada\n";
socket_write($socket, $buffer, strlen($buffer));

$recibido = socket_read($socket, 1000000, PHP_NORMAL_READ);

echo $recibido;

socket_close($socket);

Любая помощь или вопросы приветствуются!

С наилучшими пожеланиями из Монтевидео

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]