阅读长时间运行的PHP进程客户端

我想读一个长期运行的PHP过程,当满足条件时将返回数据。

从我的研究中,我遇到了:

  • 长期投票
  • 套接字(socket.io&node.js)
  • 棘轮

我正在努力理解和实施我的问题。 我在PHP中有以下循环:

public function store(ClientImpl $a) { $request = \Illuminate\Support\Facades\Request::all(); $originateMsg = new OriginateAction('Local/' . $request['agent'] . '@auto-answer'); $originateMsg->setContext('G-Outgoing'); $originateMsg->setPriority('1'); $originateMsg->setExtension($request['dial']); $a->send($originateMsg); while(true) { if( $a->process() ) break; usleep(1000); } $a->close(); echo 'OK'; ob_end_flush(); flush(); } 

$a->process()调用以下方法:

 /** * Main processing loop. Also called from send(), you should call this in * your own application in order to continue reading events and responses * from ami. */ public function process() { $msgs = $this->getMessages(); foreach ($msgs as $aMsg) { if ($this->_logger->isDebugEnabled()) { $this->_logger->debug( '------ Received: ------ ' . "\n" . $aMsg . "\n\n" ); } $resPos = strpos($aMsg, 'Response:'); $evePos = strpos($aMsg, 'Event:'); if (($resPos !== false) && (($resPos < $evePos) || $evePos === false)) { $response = $this->_messageToResponse($aMsg); $this->_incomingQueue[$response->getActionId()] = $response; } else if ($evePos !== false) { $event = $this->_messageToEvent($aMsg); $response = $this->findResponse($event); if ($response === false || $response->isComplete()) { $this->dispatch($event); } else { $response->addEvent($event); } } else { // broken ami.. sending a response with events without // Event and ActionId $bMsg = 'Event: ResponseEvent' . "\r\n"; $bMsg .= 'ActionId: ' . $this->_lastActionId . "\r\n" . $aMsg; $event = $this->_messageToEvent($bMsg); $response = $this->findResponse($event); $response->addEvent($event); } if ($this->_logger->isDebugEnabled()) { $this->_logger->debug('----------------'); } } } 

$a->process()然后堆积事件消息,读取这些我创build一个IEventListener的实现,也称为“幕后”,当$a->process()被调用。

 class VoipEventStart implements IEventListener { public function handle(EventMessage $event) { $a = $event->getKeys(); if( ($a['event'] == "Hangup" || $a['event'] == "HangupRequest") && strpos($a['channel'], 'SIP/') !== FALSE) { return true; } return false; } } 

处理方法在用户正在进行通话时从Asterisk PBX系统读取事件。 这意味着只要通话持续,处理循环就会持续。

我怎么会执行这个客户端没有浏览器看起来像加载/等待?

你可以使用服务器发送事件或一些套接字的实现,但最简单的可能是一个长期的民意调查策略将工作得很好。

为此,从客户端发送一个普通的AJAX请求,并使服务器只有在满足条件时才会返回。 这可以像更改服务器端代码一样简单,如下所示:

 while(true) { if( $a->process() ) break; usleep(1000); } echo 'OK'; ob_end_flush(); flush(); 

客户端应该发送一个简单的GET请求到启动上述循环的PHP文件。 这样,当一个响应返回到这个请求时,你知道process()返回true。

客户端代码可能如下所示:

 <div>Call status: <span id="status">In call</span></div> <script> $.get('/check_call_status.php?callerId=123', function(response) { if(response === 'OK') { $('#staus').html('finished'); } }); </script> 

当然,这可能是更复杂的处理超时。 例如,如果在给定的时间段内没有响应长时间轮询请求,请重新启动它 – 即中止请求并再次发送,以避免客户端或服务器超时。