2016-07-07 1 views
1

PHP에서 프록시 유형을 쓰고 있습니다.PHP 여러 가지 일을하는 동안 스레딩

이 프록시는 서버에 대해 몇 개의 연결을 만들고, 다른 명령을 보내지 않으면 "ping"패킷을 너무 자주 보내서 연결을 유지합니다.

클라이언트는 프록시에 연결하여 서버에 메시지를 전달할 수 있어야합니다. 이 경우 프록시는 현재 사용 중이 아닌 연결 중 하나를 선택하고 (여러 클라이언트가 연결되어 있고 요청 중 하나가 시간이 걸릴 경우) 비활 성 연결을 사용합니다.

어떻게하면 좋을지에 대한 제 아이디어 : RabbitMQ를 대기열로 사용하십시오. 클라이언트는 RabbitMQ에 메시지를 제출하고 응답을 기다립니다. 서버 측에서는 모든 연결이 자체 스레드가되며 모든 스레드는 RabbitMQ에서 계속 작업을 기다리고 있으며 처음에는 RabbitMQ에서 메시지를 가져 오는 것이 요청을 수행합니다. 하지만이 경우에는 연결 스레드가 끊임없이 작업 대기 중이므로 작업이없는 경우 Keepalive 패킷을 어떻게 보냅니 까?

이것이 나쁜 생각 인 경우 어떻게 제대로 수행 할 수 있습니까?

답변

0

구조적으로 스레드는이 문제를 해결할 수있는 좋은 방법이므로이 문제에 대해 확실히 생각하고 있습니다. 불행히도 PHP는 쓰레드를 지원하지 않습니다! 따라서 pcntl_fork() 대신 개의 프로세스을 사용해야합니다. Here's an example (내 코드 아님), 스레드 대신 각 연결을 처리하는 새로운 프로세스를 생성합니다.

/** 
* Connection handler 
*/ 
function onConnect($client) { 
    $pid = pcntl_fork(); 

    if ($pid == -1) { 
     die('could not fork'); 
    } else if ($pid) { 
     // parent process 
     return; 
    } 

    $read = ''; 
    printf("[%s] Connected at port %d\n", $client->getAddress(), $client->getPort()); 

    while(true) { 
     $read = $client->read(); 
     if($read != '') { 
      $client->send('[' . date(DATE_RFC822) . '] ' . $read ); 
     } 
     else { 
      break; 
     } 

     if(preg_replace('/[^a-z]/', '', $read) == 'exit') { 
      break; 
     } 
     if($read === null) { 
      printf("[%s] Disconnected\n", $client->getAddress()); 
      return false; 
     } 
     else { 
      printf("[%s] recieved: %s", $client->getAddress(), $read); 
     } 
    } 
    $client->close(); 
    printf("[%s] Disconnected\n", $client->getAddress()); 

} 
require "sock/SocketServer.php"; 
$server = new \Sock\SocketServer(); 
$server->init(); 
$server->setConnectionHandler('onConnect'); 
$server->listen(); 

킵 얼라이브를 보내는 스레드가 필요하다고하셨습니다. 가장 간단한 해결책은 pnctl_fork() 하나의 추가 프로세스이며 다른 프로세스가 사용 중일 때 keepalives를 보내는 데 사용하는 것입니다.

keepalive 메시지의 경우에는 분기 연결 핸들러 프로세스에서이를 수행 할 수 있습니다. 그런 다음 연결 처리기 프로세스 아래에서 또 다른 분기 된 프로세스에서 실제 작업을 수행하십시오.

+0

이 질문은 매우 광범위한 질문이므로 답을 통해 더 구체적으로 설명하기가 어렵습니다. – Will

+0

Ok - pcntl_fork()에 대해서도 읽었습니다. 하지만 클라이언트가 프록시에 연결되어있는 한 그 스레드는 지속되지 않겠습니까? 예, 내 클라이언트가 연결됩니다 -> 새 프로세스가 클라이언트를 처리하기 시작 -> 클라이언트 연결 끊기 -> 프로세스가 종료됩니다. – derp

+0

클라이언트가 연결을 끊어도 프로세스가 자동으로 종료되지 않습니다. 작업이 완료되기 전에 클라이언트의 연결이 끊어지면 작업자 프로세스 풀이 완전히 분리되어야하고 클라이언트는 백그라운드 작업자 프로세스가 처리하는 큐와 상호 작용할 수 있습니다. – Will

관련 문제