2013-07-16 4 views
3

상황 :매 X 초마다 PHP 메소드를 실행 하시겠습니까?

난 그냥 다른 루프를 만들 수 있도록 내가 분명히 소켓 연결 및 수신 데이터를 듣고 메인 루프가있는 데몬으로 실행하는 PHP 웹 소켓 서버 (here)를 만들고 있어요 sleep(x_number_of_seconds);은 내 전체 서버를 고정시킬 것이기 때문에

CRON 작업으로 외부 스크립트를 실행하거나 연결된 클라이언트 소켓에 데이터를 보내려면 내 서버 클래스의 범위에 있어야하기 때문에 새로운 프로세스를 포크 할 수 없습니다.

누구든지 PHP에서 이것을 달성하기위한 마술을 알고 있습니까? :/

어떤 미친 아이디어 : microtime(true)와 마지막 루프 실행 시간의

  1. 를 추적하려면, 그리고 내 원하는 X 초 간격에 대해 있다면, 각 루프의 현재 시간과 비교, 실행 그 방법은 ... 매우 마시고 일관성없는 간격 루프를 초래할 것입니다.
  2. 내 서버 물마루 websocket와 통신하고 내 방법을 실행하도록 알리는 브라우저에서 JavaScript를 실행하십시오. 나는 그들이 어디에 미친 아이디어를 말했습니다! 나는 모든 X 자신의 행동을 갱신 일부의 NPC를 추가하고자하는 작은 온라인 게임 (와 같은 RPG)을 만들고있어

    을 : 난 달성하기 위해 노력하고있어 약

추가 정보를 정기적으로 초.

다른 방법이 있습니까? 내가 놓친 게 있니? Node.js에서 서버를 다시 작성해야합니까 ??

도움을 주셔서 감사합니다.

+1

# 1 + select()에 대한 작은 시간 초과는 어떻게 수행합니까? – goat

답변

2

완벽한 대안에 그래서 난 내 미친 솔루션 # 1을 사용합니다 존재 솔기하지 않습니다

$this->last_tick_time = microtime(true); 
$this->tick_interval = 1; 
$this->tick_counter = 0; 

while(true) 
{ 
    //loop code here... 

    $t= microtime(true) - $this->last_tick_time; 

    if($t>= $this->tick_interval) 
    { 
     $this->on_server_tick(++$this->tick_counter); 
     $this->last_tick_time = microtime(true) - ($t- $this->tick_interval); 
    } 
} 

기본적으로, 마지막 서버 틱 내 원하는 틱보다 크거나 같아야하기 때문에 시간이 경과 된 경우 간격, on_server_tick() 메서드를 실행하십시오. 그리고 가장 중요하게는 : 우리는 너무 늦게 일어난다면 다음 틱이 더 빨리 일어날 수 있도록 시간 오버 플로우를 뺍니다.우리가 간격을 채우는이 방법으로, socket_select 시간 초과가 1 초로 설정되면, 우리는 1.99999999+ 초보다 큰 간격을 결코 가지지 않을 것입니다. 나는 또한 틱 카운터를 추적

, 내가 에 모듈로 (%)를 사용할 수있는이 방법은 여러 간격에서이 같은를 코드를 실행 :

protected function on_server_tick($counter) 
{ 
    if($counter%5 == 0) 
    { 
     // 5 seconds interval 
    } 

    if($counter%10 == 0) 
    { 
     // 10 seconds interval 
    } 
} 

어떤 내 모든 요구를 커버! : D

PHP는 걱정하지 않으셔도됩니다. Node.js로 바꾸지 않으 시겠지만, 여전히 내 친구입니다.

0

당신이 사용하고있는 websocket-framework가 클라이언트로부터의 연결을 기다리는 동안 서버가 다른 유용한 일을 할 수 있도록 너무 원시적 인 것처럼 보입니다. PHP의 socket_select() 함수에 대한 유일한 호출은 1 초의 타임 아웃으로 하드 코딩되어 있으며, 시간이 다되면 아무 일도하지 않습니다. 정말 콜백이나 외부 루프를 허용해야합니다.

http://php.net/manual/en/function.socket-select.php 매뉴얼 페이지를보십시오. 마지막 매개 변수는 시간 종료 시간입니다. socket_select()는 소켓에서 들어오는 데이터를 기다리거나 타임 아웃 시간이 다가올 때까지 기다린다. 이것은 당신이하고 싶은 것처럼 들리나 라이브러리에는 아무런 준비가 없다. 그런 다음 라이브러리가 core/classes/SocketServer.php에서 라이브러리를 사용하는 방법을 살펴보십시오.

나는 run()을 호출했다고 가정하고, 아무 것도하지 못하도록 소켓에서 메시지를 얻을 때까지 호출 코드로 리턴하지 않는다.

+0

실제로이 프레임 워크를 "사용하고 있지는 않습니다."나는이 프레임 워크를 사용하고 있습니다 : P 그렇습니다.이 시간 초과는 성공에 대한 첫 번째 희망이었습니다. 그것은 매 1 초마다 루프를 실행할 수있게 해줍니다. 그러나 데이터가 수신 되 자마자 서버가 루프를 실행하기 때문에 (1 초 제한 시간 전에) 서버가 데이터를 수신하지 않는 경우에만 작동합니다. 따라서 그 것에 의존 할 수 없습니다. : – WiMantis

+0

일부 분기 코드는 어떨까요? 시간 초과 또는 socket_select()가 완료되는 원인이 된 데이터 수신 여부를 확인한 다음 상황에 맞는 적절한 작업을 수행하십시오. – CXJ

+0

그런 다음 서버가 1보다 짧은 간격으로 데이터를 수신하는 경우 두 번째, 시간 제한은이 시간 초과가 함수가 끝날 때마다 재설정되므로 내 메서드가 실행되지 않도록하기 위해 함수가 종료되지 않습니다./ – WiMantis