From: Bryan Duxbury Date: Thu, 12 Aug 2010 16:59:19 +0000 (+0000) Subject: THRIFT-778. php: PHP socket listening server X-Git-Tag: 0.4.0~16 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=17115d7a528b6351fc230fe73b6d765b8e186264;p=common%2Fthrift.git THRIFT-778. php: PHP socket listening server This patch which adds TServerTransport/TServerSocket, along with a generic TServer and TSimpleServer implementation. Patch: Nick Jones git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@984864 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/lib/php/src/protocol/TProtocol.php b/lib/php/src/protocol/TProtocol.php index be47100f..ac1facde 100644 --- a/lib/php/src/protocol/TProtocol.php +++ b/lib/php/src/protocol/TProtocol.php @@ -368,7 +368,7 @@ interface TProtocolFactory { /** * Build a protocol from the base transport * - * @return TProtcol protocol + * @return TProtocol protocol */ public function getProtocol($trans); } diff --git a/lib/php/src/server/TServer.php b/lib/php/src/server/TServer.php new file mode 100644 index 00000000..b25a9ee2 --- /dev/null +++ b/lib/php/src/server/TServer.php @@ -0,0 +1,95 @@ +processor_ = $processor; + $this->transport_ = $transport; + $this->inputTransportFactory_ = $inputTransportFactory; + $this->outputTransportFactory_ = $outputTransportFactory; + $this->inputProtocolFactory_ = $inputProtocolFactory; + $this->outputProtocolFactory_ = $outputProtocolFactory; + } + + /** + * Serves the server. This should never return + * unless a problem permits it to do so or it + * is interrupted intentionally + * + * @abstract + * @return void + */ + abstract public function serve(); + + /** + * Stops the server serving + * + * @abstract + * @return void + */ + abstract public function stop(); +} diff --git a/lib/php/src/server/TSimpleServer.php b/lib/php/src/server/TSimpleServer.php new file mode 100644 index 00000000..f7d0a328 --- /dev/null +++ b/lib/php/src/server/TSimpleServer.php @@ -0,0 +1,54 @@ +transport_->listen(); + + while (!$this->stop_) { + try { + $transport = $this->transport_->accept(); + + if ($transport != null) { + $inputTransport = $this->inputTransportFactory_->getTransport($transport); + $outputTransport = $this->outputTransportFactory_->getTransport($transport); + $inputProtocol = $this->inputProtocolFactory_->getProtocol($inputTransport); + $outputProtocol = $this->outputProtocolFactory_->getProtocol($outputTransport); + while ($this->processor_->process($inputProtocol, $outputProtocol)) { } + } + } + catch (TTransportException $e) { } + } + } + + /** + * Stops the server running. Kills the transport + * and then stops the main serving loop + * + * @return void + */ + public function stop() { + $this->transport_->close(); + $this->stop_ = true; + } +} diff --git a/lib/php/src/transport/TServerSocket.php b/lib/php/src/transport/TServerSocket.php new file mode 100644 index 00000000..cac12ab7 --- /dev/null +++ b/lib/php/src/transport/TServerSocket.php @@ -0,0 +1,96 @@ +host_ = $host; + $this->port_ = $port; + } + + /** + * Sets the accept timeout + * + * @param int $acceptTimeout + * @return void + */ + public function setAcceptTimeout($acceptTimeout) { + $this->acceptTimeout_ = $acceptTimeout; + } + + /** + * Opens a new socket server handle + * + * @return void + */ + public function listen() { + $this->listener_ = stream_socket_server('tcp://' . $this->host_ . ':' . $this->port_); + } + + /** + * Closes the socket server handle + * + * @return void + */ + public function close() { + @fclose($this->listener_); + $this->listener_ = null; + } + + /** + * Implementation of accept. If not client is accepted in the given time + * + * @return TSocket + */ + protected function acceptImpl() { + $handle = @stream_socket_accept($this->listener_, $this->acceptTimeout_ / 1000.0); + if(!$handle) return null; + + $socket = new TSocket(); + $socket->setHandle($handle); + + return $socket; + } +} diff --git a/lib/php/src/transport/TServerTransport.php b/lib/php/src/transport/TServerTransport.php new file mode 100644 index 00000000..e92ca77c --- /dev/null +++ b/lib/php/src/transport/TServerTransport.php @@ -0,0 +1,50 @@ +acceptImpl(); + + if ($transport == null) { + throw new TTransportException("accept() may not return NULL"); + } + + return $transport; + } +} diff --git a/lib/php/src/transport/TSocket.php b/lib/php/src/transport/TSocket.php index a3000f73..bbe19875 100644 --- a/lib/php/src/transport/TSocket.php +++ b/lib/php/src/transport/TSocket.php @@ -109,6 +109,14 @@ class TSocket extends TTransport { $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log'; } + /** + * @param resource $handle + * @return void + */ + public function setHandle($handle) { + $this->handle_ = $handle; + } + /** * Sets the send timeout. * @@ -167,6 +175,17 @@ class TSocket extends TTransport { * Connects the socket. */ public function open() { + if ($this->isOpen()) { + throw new TTransportException('Socket already connected', TTransportException::ALREADY_OPEN); + } + + if (empty($this->host_)) { + throw new TTransportException('Cannot open null host', TTransportException::NOT_OPEN); + } + + if ($this->port_ <= 0) { + throw new TTransportException('Cannot open without port', TTransportException::NOT_OPEN); + } if ($this->persist_) { $this->handle_ = @pfsockopen($this->host_, @@ -225,16 +244,16 @@ class TSocket extends TTransport { if ($buf === FALSE || $buf === '') { $md = stream_get_meta_data($this->handle_); if ($md['timed_out']) { - throw new TException('TSocket: timed out reading '.$len.' bytes from '. + throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '. $this->host_.':'.$this->port_); } else { - throw new TException('TSocket: Could not read '.$len.' bytes from '. + throw new TTransportException('TSocket: Could not read '.$len.' bytes from '. $this->host_.':'.$this->port_); } } else if (($sz = strlen($buf)) < $len) { $md = stream_get_meta_data($this->handle_); if ($md['timed_out']) { - throw new TException('TSocket: timed out reading '.$len.' bytes from '. + throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '. $this->host_.':'.$this->port_); } else { $pre .= $buf; @@ -261,10 +280,10 @@ class TSocket extends TTransport { if ($data === FALSE || $data === '') { $md = stream_get_meta_data($this->handle_); if ($md['timed_out']) { - throw new TException('TSocket: timed out reading '.$len.' bytes from '. + throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '. $this->host_.':'.$this->port_); } else { - throw new TException('TSocket: Could not read '.$len.' bytes from '. + throw new TTransportException('TSocket: Could not read '.$len.' bytes from '. $this->host_.':'.$this->port_); } } @@ -286,10 +305,10 @@ class TSocket extends TTransport { if ($got === 0 || $got === FALSE) { $md = stream_get_meta_data($this->handle_); if ($md['timed_out']) { - throw new TException('TSocket: timed out writing '.strlen($buf).' bytes from '. + throw new TTransportException('TSocket: timed out writing '.strlen($buf).' bytes from '. $this->host_.':'.$this->port_); } else { - throw new TException('TSocket: Could not write '.strlen($buf).' bytes '. + throw new TTransportException('TSocket: Could not write '.strlen($buf).' bytes '. $this->host_.':'.$this->port_); } } diff --git a/lib/php/src/transport/TTransportFactory.php b/lib/php/src/transport/TTransportFactory.php new file mode 100644 index 00000000..ac0a65ac --- /dev/null +++ b/lib/php/src/transport/TTransportFactory.php @@ -0,0 +1,12 @@ +