Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | Last modification | View Log | RSS feed

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