php socket不一致的结果

时间:2014-05-09 02:55:50

标签: php json sockets connection-timeout

我正面临一个问题,我对PHP套接字并不是很了解;由于通信似乎不稳定,我得到“非一致”的结果,我无法想象如何设置流超时。

长篇短篇小说:我试图获得一个客户端通过VPN连接的套接字服务器(我知道,我的服务器现在不是多线程的...,我需要更多的技能!)来获取我今天关注的最新配置为星号生成多个配置文件。服务器是一个简单的PHP套接字脚本socket.php,客户端由任何模块的网关action.php组成,这些模块使用各自应用程序/目录中的php-cli脚本的类。所以我有例如modules/pbx/app/update_sip.php,它使用modules/pbx/classes/PbxGenerateConfig.php通过modules/api/classes/ApiServer.php套接字客户端从套接字服务器json响应中获取(并写入)配置文件。我希望每个人都清楚;)

以下是一些摘录(请不要犹豫再问,因为我不知道自己错过了什么......)

socket.php

<?php

chdir(dirname(__FILE__));

require_once('classes/_Autoload_.php');
require_once('config.php');


function convertObjectToArray ($object) {
    if(!is_object($object) && !is_array($object))
        return $object;

    return array_map('convertObjectToArray', (array) $object);
}


set_time_limit (0);
$address = '0.0.0.0';
$port = 9000;

$sock = socket_create(AF_INET, SOCK_STREAM, 0); // 0 for  SQL_TCP
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 60, 'usec' => 0));

@socket_bind($sock, 0, $port) or die("Cannot bind to $address:$port\n");  //0 forlocalhost
socket_listen($sock);

#TODO fork child processes to support multiple clients & classes loads on-the-fly

while (true)
{
$client  = socket_accept($sock);
$input   = socket_read($client, 16384000);

$command = convertObjectToArray(json_decode($input));

$authentication = Database::get('management')->selectOne(array('table'     => 'components',
                                                               'fields'    => 'id,name',
                                                               'condition' => "management_access_key LIKE '{$command['access_key']}'"));

if (empty($authentication))
    $response = array('request' => array('command'=>$command['command'], 'arguments'=>$command_args, 'status' => 'error'),
                      'result'  => 'Authentication failed : invalid access key');

else if(!empty($command))
{
    $get_security_policies = Database::get('management')->selectAll(array('table'     => 'components_security_policies',
                                                                          'fields'    => 'class',
                                                                          'condition' => "component = {$authentication['id']}"));

    $security_policies = array();
    foreach ($get_security_policies as $policy) { $security_policies[] = $policy['class']; }

    unset($command['access_key']);

    if (isset($command['command']))
    {
        $command_call = explode('/',$command['command']);
        $command_args = $command; unset($command_args['command']);

        if (in_array($command_call[0],$security_policies))
        {

            #TODO check if command/function exists + try/catch
            $output = $command_call[0]::$command_call[1]($command_args);

            $response = array('request' => array('command'=>$command['command'], 'arguments'=>$command_args, 'status' => 'success'),
                              'result'  => $output);
        }

        else $response = array('request' => array('command'=>$command['command'], 'arguments'=>$command_args, 'status' => 'success'),
                               'result'  => 'Action forbidden by security policies for this access key');


    }

    else
    {
        $response = array('request' => array('command'=>NULL, 'arguments'=>NULL, 'status' => 'error'),
                          'result'  => 'Command not set');
    }


}

else $response = array('request' => array('command'=>NULL, 'arguments'=>NULL, 'status' => 'error'),
                       'result'  => 'No command received');

echo "==================== COMMAND RECEIVED ====================\n";
echo "FROM: C{$authentication['name']} (C{$authentication['id']})\n";
print_r($command); echo "\n";
echo "--------------------  RESPONSE SENT   --------------------\n";
print_r($response); echo "\n";
echo "==========================================================\n\n\n\n";

socket_write($client, json_encode($response));
socket_close($client);
}

// Close the master sockets
socket_close($sock);

action.php的

<?php
$usage = "Usage : ./{$argv[0]} <module> <class> <method> [arguments]";

if (!isset($argv[1])) die("Error : Missing argument 'module'\n$usage\n\n");

chdir(dirname(__FILE__));
if (!is_dir('../modules/'.$argv[1])) die("Error : Module '{$argv[1]}' is not installed\n\n");

fclose(STDIN);  $STDIN  = fopen('/dev/null', 'r');
#fclose(STDOUT); $STDOUT = fopen('/var/log/management-client-'.$argv[1].'.out.log',    'a');
fclose(STDERR); $STDERR = fopen('/var/log/management-client-'.$argv[1].'.error.log', 'a');

error_reporting(E_ALL);
ini_set('display_errors', true);
#ini_set('display_errors', false);

#require_once('../config/'.$argv[1].'.php');
foreach (glob("../config/*.php") as $file) { include_once($file); }
require_once('lib/cliArgsParser.php');
require_once('lib/classAutoLoader.php');

if (php_sapi_name() === 'cli')
{
$arguments = core_cliArgsParser($argv);

if (empty($arguments[2])) die("Error : Missing argument 'class'\n$usage\n\n");
if (empty($arguments[3])) die("Error : Missing argument 'method'\n$usage\n\n");

$class_name = ucfirst($arguments[1]);
$class_arguments = $arguments;
unset($class_arguments[0],$class_arguments[1],$class_arguments[2],$class_arguments[3]);

$result = $class_name::action($arguments[2])->$arguments[3]($class_arguments);
#echo json_encode($result);
print_r($result);
}
else die ('Error : Can be executed exclusively from CLI');

update_sip.php

php /usr/local/management-client/core/action.php pbx generateConfig generateSip --type=carriers --location=/ramdisk/

PbxGenerateConfig.php

(...)
public function generateSip ($args)
{
    $types = array('carriers','users');

    if (empty($args['location'])) return "Error : 'location' required\n";
    if (!in_array(@$args['type'],$types)) return "Error : type '".@$args['type']."' not supported (can be : ".implode(',',$types).")\n";

    # carriers
    if ($args['type'] == 'carriers')
    {
        $response = Api::action('server')->request(array('command'=>'PbxServer/getSipConfig', 'type'=>$args['type']));

        if ($response->result->status == 'success')
        {
            $fh = fopen(rtrim($args['location'],'/').'/sip_carriers.conf','w');
            $file_content = '';

            foreach ($response->result->data as $sip_trunk)
            {
                $file_content .="[{$sip_trunk->code}]  ; {$sip_trunk->name}\n"
                              . "{$sip_trunk->sip_settings}\n\n";
            }

            fwrite($fh,utf8_encode($file_content));
            fclose($fh);

            return "Sip {$args['type']} successfully updated\n";
        }

        else return "Sip update error\n";
    }
(...)

ApiServer.php     

class ApiServer extends Api
{

public function request ($command)
{

    global $CONFIG;

    $command['access_key'] = $CONFIG['api']['access']['key'];

    $ret = '';
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
              socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 60, 'usec' => 0));

    if ($socket === false) die("Cannot create socket : ".socket_strerror(socket_last_error())."\n");


    $result = @socket_connect($socket, $CONFIG['api']['access']['host'], $CONFIG['api']['access']['port']);

    if ($result === false)
    {
        return "Cannot connect to {$CONFIG['api']['access']['host']}:{$CONFIG['api']['access']['port']} : ".socket_strerror(socket_last_error($socket))."\n";
    }

    $cmd = json_encode($command);

    socket_write($socket, $cmd, strlen($cmd));
    #stream_set_timeout($socket, 60);

    while ($out = socket_read($socket, 16384000))
    {
        $ret = json_decode($out);
    }

    socket_close($socket);

    return $ret;
}


}

谢谢, CL

0 个答案:

没有答案