socket_select AF_UNIX PHP

时间:2014-09-29 19:14:16

标签: php sockets

我的情况有点混乱,但我会尝试解释。

我在PHP中编写OSS功能,南部接口与GPON节点对话,北部接口与整个系统的其余部分对话。

我现在正在写TL1接口与HUAWEI U2000节点通信,该节点将TL1 / SSH与我和SNMP通信到OLT。

所有32个TL1连接都由n2000管理,我正在编写服务器来处理所有连接。我已经解决了TL1 / SSH连接并且工作正常但我需要编写服务器来管理所有32个连接,队列,优先级等。

一个客户端(来自的PHP脚本和SOAP请求,例如)可以向我的服务器发送命令数组,服务器必须执行命令并发送响应。

这可以阻止服务器响应的时间,但我有32个可能的连接,所以我实现了一个FRONTENDserver和32个BACKENDserver。一个客户端在FRONTEND的AF_UNIX套接字中写入请求,服务器将其发送到空闲的BACKEND,监听其他AF_UNIX套接字以捕获响应并将响应发送给顶级客户端。

一切正常,但我遇到了问题:

我已经用2个BACKEND服务器实现了测试,并在内部设置了一些模拟阻塞,以及3个客户端脚本,cl1.php cl2.php cl3.php具有相同的代码。

when:cl1.php run - > BCKEND1入睡10秒;运行cl2.php - > BCKEND2进入睡眠状态10秒,当我运行cl3.php时,FRONTEND说"全部被占用"直到有一个免费,一切都很好...但是

如果我运行cl1.php - > sleep,cl2.php - >睡觉但是在其他标签我运行cl2.php再次FRONEND没有接到电话,他等到BKEND2空闲然后拿#34;其他" cl2.php再次打电话。

让我更加困惑的另一件事是,如果我运行cl1.php,cl2.php和NOW cl1.php?f = foo(或其他任何)IT工作正常:说"所有被占用&#34 ;

如果脚本具有相同的名称,则在关闭另一个实例之前不会触发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 pedidos


    if(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);

CLIENTS 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 个答案:

没有答案