Overview

Packages

  • None
  • thrift
    • transport

Classes

  • TBufferedTransport
  • TFramedTransport
  • THttpClient
  • TMemoryBuffer
  • TNullTransport
  • TPhpStream
  • TSocket
  • TSocketPool
  • TTransport
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Copyright (c) 2006- Facebook
  5:  * Distributed under the Thrift Software License
  6:  *
  7:  * See accompanying file LICENSE or visit the Thrift site at:
  8:  * http://developers.facebook.com/thrift/
  9:  *
 10:  * @package thrift.transport
 11:  * @author Mark Slee <mcslee@facebook.com>
 12:  */
 13: 
 14: /**
 15:  * Sockets implementation of the TTransport interface.
 16:  *
 17:  * @package thrift.transport
 18:  * @author Mark Slee <mcslee@facebook.com>
 19:  */
 20: class TSocket extends TTransport {
 21: 
 22:   /**
 23:    * Handle to PHP socket
 24:    *
 25:    * @var resource
 26:    */
 27:   private $handle_ = null;
 28: 
 29:   /**
 30:    * Remote hostname
 31:    *
 32:    * @var string
 33:    */
 34:   protected $host_ = 'localhost';
 35: 
 36:   /**
 37:    * Remote port
 38:    *
 39:    * @var int
 40:    */
 41:   protected $port_ = '9090';
 42: 
 43:   /**
 44:    * Send timeout in milliseconds
 45:    *
 46:    * @var int
 47:    */
 48:   private $sendTimeout_ = 100;
 49: 
 50:   /**
 51:    * Recv timeout in milliseconds
 52:    *
 53:    * @var int
 54:    */
 55:   private $recvTimeout_ = 750;
 56: 
 57:   /**
 58:    * Is send timeout set?
 59:    *
 60:    * @var bool
 61:    */
 62:   private $sendTimeoutSet_ = FALSE;
 63: 
 64:   /**
 65:    * Persistent socket or plain?
 66:    *
 67:    * @var bool
 68:    */
 69:   private $persist_ = FALSE;
 70: 
 71:   /**
 72:    * Debugging on?
 73:    *
 74:    * @var bool
 75:    */
 76:   protected $debug_ = FALSE;
 77: 
 78:   /**
 79:    * Debug handler
 80:    *
 81:    * @var mixed
 82:    */
 83:   protected $debugHandler_ = null;
 84: 
 85:   /**
 86:    * Socket constructor
 87:    *
 88:    * @param string $host         Remote hostname
 89:    * @param int    $port         Remote port
 90:    * @param bool   $persist      Whether to use a persistent socket
 91:    * @param string $debugHandler Function to call for error logging
 92:    */
 93:   public function __construct($host='localhost',
 94:                               $port=9090,
 95:                               $persist=FALSE,
 96:                               $debugHandler=null) {
 97:     $this->host_ = $host;
 98:     $this->port_ = $port;
 99:     $this->persist_ = $persist;
100:     $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
101:   }
102: 
103:   /**
104:    * Sets the send timeout.
105:    *
106:    * @param int $timeout
107:    */
108:   public function setSendTimeout($timeout) {
109:     $this->sendTimeout_ = $timeout;
110:   }
111: 
112:   /**
113:    * Sets the receive timeout.
114:    *
115:    * @param int $timeout
116:    */
117:   public function setRecvTimeout($timeout) {
118:     $this->recvTimeout_ = $timeout;
119:   }
120: 
121:   /**
122:    * Sets debugging output on or off
123:    *
124:    * @param bool $debug
125:    */
126:   public function setDebug($debug) {
127:     $this->debug_ = $debug;
128:   }
129: 
130:   /**
131:    * Get the host that this socket is connected to
132:    *
133:    * @return string host
134:    */
135:   public function getHost() {
136:     return $this->host_;
137:   }
138: 
139:   /**
140:    * Get the remote port that this socket is connected to
141:    *
142:    * @return int port
143:    */
144:   public function getPort() {
145:     return $this->port_;
146:   }
147: 
148:   /**
149:    * Tests whether this is open
150:    *
151:    * @return bool true if the socket is open
152:    */
153:   public function isOpen() {
154:     return is_resource($this->handle_);
155:   }
156: 
157:   /**
158:    * Connects the socket.
159:    */
160:   public function open() {
161: 
162:     if ($this->persist_) {
163:       $this->handle_ = @pfsockopen($this->host_,
164:                                    $this->port_,
165:                                    $errno,
166:                                    $errstr,
167:                                    $this->sendTimeout_/1000.0);
168:     } else {
169:       $this->handle_ = @fsockopen($this->host_,
170:                                   $this->port_,
171:                                   $errno,
172:                                   $errstr,
173:                                   $this->sendTimeout_/1000.0);
174:     }
175: 
176:     // Connect failed?
177:     if ($this->handle_ === FALSE) {
178:       $error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
179:       if ($this->debug_) {
180:         call_user_func($this->debugHandler_, $error);
181:       }
182:       throw new TException($error);
183:     }
184: 
185:     stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
186:     $this->sendTimeoutSet_ = TRUE;
187:   }
188: 
189:   /**
190:    * Closes the socket.
191:    */
192:   public function close() {
193:     if (!$this->persist_) {
194:       @fclose($this->handle_);
195:       $this->handle_ = null;
196:     }
197:   }
198: 
199:   /**
200:    * Uses stream get contents to do the reading
201:    *
202:    * @param int $len How many bytes
203:    * @return string Binary data
204:    */
205:   public function readAll($len) {
206:     if ($this->sendTimeoutSet_) {
207:       stream_set_timeout($this->handle_, 0, $this->recvTimeout_*1000);
208:       $this->sendTimeoutSet_ = FALSE;
209:     }
210:     // This call does not obey stream_set_timeout values!
211:     // $buf = @stream_get_contents($this->handle_, $len);
212: 
213:     $pre = null;
214:     while (TRUE) {
215:       $buf = @fread($this->handle_, $len);
216:       if ($buf === FALSE || $buf === '') {
217:         $md = stream_get_meta_data($this->handle_);
218:         if ($md['timed_out']) {
219:           throw new TException('TSocket: timed out reading '.$len.' bytes from '.
220:                                $this->host_.':'.$this->port_);
221:         } else {
222:           throw new TException('TSocket: Could not read '.$len.' bytes from '.
223:                                $this->host_.':'.$this->port_);
224:         }
225:       } else if (($sz = strlen($buf)) < $len) {
226:         $md = stream_get_meta_data($this->handle_);
227:         if ($md['timed_out']) {
228:           throw new TException('TSocket: timed out reading '.$len.' bytes from '.
229:                                $this->host_.':'.$this->port_);
230:         } else {
231:           $pre .= $buf;
232:           $len -= $sz;
233:         }
234:       } else {
235:         return $pre.$buf;
236:       }
237:     }
238:   }
239: 
240:   /**
241:    * Read from the socket
242:    *
243:    * @param int $len How many bytes
244:    * @return string Binary data
245:    */
246:   public function read($len) {
247:     if ($this->sendTimeoutSet_) {
248:       stream_set_timeout($this->handle_, 0, $this->recvTimeout_*1000);
249:       $this->sendTimeoutSet_ = FALSE;
250:     }
251:     $data = @fread($this->handle_, $len);
252:     if ($data === FALSE || $data === '') {
253:       $md = stream_get_meta_data($this->handle_);
254:       if ($md['timed_out']) {
255:         throw new TException('TSocket: timed out reading '.$len.' bytes from '.
256:                              $this->host_.':'.$this->port_);
257:       } else {
258:         throw new TException('TSocket: Could not read '.$len.' bytes from '.
259:                              $this->host_.':'.$this->port_);
260:       }
261:     }
262:     return $data;
263:   }
264: 
265:   /**
266:    * Write to the socket.
267:    *
268:    * @param string $buf The data to write
269:    */
270:   public function write($buf) {
271:     if (!$this->sendTimeoutSet_) {
272:       stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
273:       $this->sendTimeoutSet_ = TRUE;
274:     }
275:     while (strlen($buf) > 0) {
276:       $got = @fwrite($this->handle_, $buf);
277:       if ($got === 0 || $got === FALSE) {
278:         $md = stream_get_meta_data($this->handle_);
279:         if ($md['timed_out']) {
280:           throw new TException('TSocket: timed out writing '.strlen($buf).' bytes from '.
281:                                $this->host_.':'.$this->port_);
282:         } else {
283:             throw new TException('TSocket: Could not write '.strlen($buf).' bytes '.
284:                                  $this->host_.':'.$this->port_);
285:         }
286:       }
287:       $buf = substr($buf, $got);
288:     }
289:   }
290: 
291:   /**
292:    * Flush output to the socket.
293:    */
294:   public function flush() {
295:     $ret = fflush($this->handle_);
296:     if ($ret === FALSE) {
297:       throw new TException('TSocket: Could not flush: '.
298:                            $this->host_.':'.$this->port_);
299:     }
300:   }
301: }
302: 
303: ?>
304: 
API documentation generated by ApiGen