summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Duedal <hd@onlinecity.dk>2011-07-22 20:14:40 +0200
committerHans Duedal <hd@onlinecity.dk>2011-07-22 20:14:40 +0200
commit3d1329a02f3f8bf08df4ddb4b7929d4574efed24 (patch)
tree656eb4ba776b95f855418f4a663d4649e3ca60da
parent61c99fc84e22696a84b45661ac223dfb5911e849 (diff)
downloadphp-smpp-3d1329a02f3f8bf08df4ddb4b7929d4574efed24.zip
php-smpp-3d1329a02f3f8bf08df4ddb4b7929d4574efed24.tar.gz
php-smpp-3d1329a02f3f8bf08df4ddb4b7929d4574efed24.tar.bz2
Replaced thrift socket components with new SocketTransport class. Moved files to new dir. Added feature to check for enquire link messages for transmitters as well
-rw-r--r--README.md23
-rw-r--r--gsmencoder.class.php (renamed from protocol/gsmencoder.class.php)0
-rw-r--r--smppclient.class.php (renamed from protocol/smppclient.class.php)39
-rw-r--r--sockettransport.class.php378
-rw-r--r--transport/LICENSE324
-rw-r--r--transport/texception.class.php2
-rw-r--r--transport/tsocket.class.php331
-rw-r--r--transport/tsocketpool.class.php294
-rw-r--r--transport/ttransport.class.php108
9 files changed, 424 insertions, 1075 deletions
diff --git a/README.md b/README.md
index cb4c0fb..0b6da9d 100644
--- a/README.md
+++ b/README.md
@@ -17,13 +17,12 @@ To send a SMS you can do:
``` php
<?php
-$GLOBALS['SMPP_ROOT'] = dirname(__FILE__); // assumes this file is in the root
-require_once $GLOBALS['SMPP_ROOT'].'/protocol/smppclient.class.php';
-require_once $GLOBALS['SMPP_ROOT'].'/protocol/gsmencoder.class.php';
-require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
+require_once 'smppclient.class.php';
+require_once 'gsmencoder.class.php';
+require_once 'sockettransport.class.php';
// Construct transport and client
-$transport = new TSocket('your.smsc.com',2775);
+$transport = new SocketTransport(array('smpp.provider.com'),3600);
$transport->setRecvTimeout(10000);
$smpp = new SmppClient($transport);
@@ -37,11 +36,12 @@ $smpp->bindTransmitter("USERNAME","PASSWORD");
// Optional connection specific overrides
//SmppClient::$sms_null_terminate_octetstrings = false;
//SmppClient::$sms_use_msg_payload_for_csms = true;
+//SmppClient::$sms_registered_delivery_flag = SMPP::REG_DELIVERY_SMSC_BOTH;
// Prepare message
$message = 'H€llo world';
$encodedMessage = GsmEncoder::utf8_to_gsm0338($message);
-$from = new SmppAddress(GsmEncoder::utf8_to_gsm0338('SMPP Tést'),SMPP::TON_ALPHANUMERIC);
+$from = new SmppAddress(SMPP Test',SMPP::TON_ALPHANUMERIC);
$to = new SmppAddress(4512345678,SMPP::TON_INTERNATIONAL,SMPP::NPI_E164);
// Send
@@ -55,12 +55,11 @@ To receive a SMS (or delivery receipt):
``` php
<?php
-$GLOBALS['SMPP_ROOT'] = dirname(__FILE__); // assumes this file is in the root
-require_once $GLOBALS['SMPP_ROOT'].'/protocol/smppclient.class.php';
-require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
+require_once 'smppclient.class.php';
+require_once 'sockettransport.class.php';
// Construct transport and client
-$transport = new TSocket('your.smsc.com',2775);
+$transport = new SocketTransport(array('smpp.provider.com'),3600);
$transport->setRecvTimeout(60000); // for this example wait up to 60 seconds for data
$smpp = new SmppClient($transport);
@@ -85,9 +84,9 @@ Implementation notes
- You can't connect as a transceiver, otherwise supported by SMPP v.3.4
- The SUBMIT_MULTI operation of SMPP, which sends a SMS to a list of recipients, is not supported atm. You can easily add it though.
- - The thrift sockets will return false if the timeout is reached (after version 0.6.0).
+ - The sockets will return false if the timeout is reached on read() (but not readAll or write).
You can use this feature to implement an enquire_link policy. If you need to send enquire_link for every 30 seconds of inactivity,
- set a timeout of 30 seconds, and send the enquire_link command if readSMS() returns false.
+ set a timeout of 30 seconds, and send the enquire_link command after readSMS() returns false.
- The examples above assume that the SMSC default datacoding is [GSM 03.38](http://en.wikipedia.org/wiki/GSM_03.38).
- Remember to activate registered delivery if you want delivery receipts (set to SMPP::REG_DELIVERY_SMSC_BOTH / 0x01).
- Both the SmppClient and transport components support a debug callback, which defaults to error_log. Use this to redirect debug information. \ No newline at end of file
diff --git a/protocol/gsmencoder.class.php b/gsmencoder.class.php
index 5c1ffe5..5c1ffe5 100644
--- a/protocol/gsmencoder.class.php
+++ b/gsmencoder.class.php
diff --git a/protocol/smppclient.class.php b/smppclient.class.php
index 945f247..ad24b4e 100644
--- a/protocol/smppclient.class.php
+++ b/smppclient.class.php
@@ -1,5 +1,5 @@
<?php
-require_once $GLOBALS['SMPP_ROOT'].'/transport/ttransport.class.php';
+require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'sockettransport.class.php';
/**
* Class for receiving or sending sms through SMPP protocol.
@@ -72,10 +72,10 @@ class SmppClient
/**
* Construct the SMPP class
*
- * @param TTransport $transport
+ * @param SocketTransport $transport
* @param string $debugHandler
*/
- public function __construct(TTransport $transport,$debugHandler=null)
+ public function __construct(SocketTransport $transport,$debugHandler=null)
{
// Internal parameters
$this->sequence_number=1;
@@ -457,6 +457,37 @@ class SmppClient
}
/**
+ * Respond to any enquire link we might have waiting.
+ * If will check the queue first and respond to any enquire links we have there.
+ * Then it will move on to the transport, and if the first PDU is enquire link respond,
+ * otherwise add it to the queue and return.
+ *
+ */
+ public function respondEnquireLink()
+ {
+ // Check the queue first
+ $ql = count($this->pdu_queue);
+ for($i=0;$i<$ql;$i++) {
+ $pdu=$this->pdu_queue[$i];
+ if($pdu->id==SMPP::ENQUIRE_LINK) {
+ //remove response
+ array_splice($this->pdu_queue, $i, 1);
+ $this->sendPDU(new SmppPdu(SMPP::ENQUIRE_LINK_RESP, SMPP::ESME_ROK, $pdu->sequence, "\x00"));
+ }
+ }
+
+ // Check the transport for data
+ if ($this->transport->hasData()) {
+ $pdu = $this->readPDU();
+ if($pdu->id==SMPP::ENQUIRE_LINK) {
+ $this->sendPDU(new SmppPdu(SMPP::ENQUIRE_LINK_RESP, SMPP::ESME_ROK, $pdu->sequence, "\x00"));
+ } else {
+ array_push($this->pdu_queue, $pdu);
+ }
+ }
+ }
+
+ /**
* Reconnect to SMSC.
* This is mostly to deal with the situation were we run out of sequence numbers
*/
@@ -514,7 +545,7 @@ class SmppClient
call_user_func($this->debugHandler, ' command_id : 0x'.dechex($pdu->id));
call_user_func($this->debugHandler, ' sequence number : '.$pdu->sequence);
}
- $this->transport->write($header.$pdu->body);
+ $this->transport->write($header.$pdu->body,$length);
}
/**
diff --git a/sockettransport.class.php b/sockettransport.class.php
new file mode 100644
index 0000000..572b4c4
--- /dev/null
+++ b/sockettransport.class.php
@@ -0,0 +1,378 @@
+<?php
+
+/**
+ * TCP Socket Transport for use with multiple protocols.
+ * Supports connection pools and IPv6 in addition to providing a few public methods to make life easier.
+ * It's primary purpose is long running connections, since it don't support socket re-use, ip-blacklisting, etc.
+ * It assumes a blocking/synchronous architecture, and will block when reading or writing, but will enforce timeouts.
+ *
+ * Copyright (C) 2011 OnlineCity
+ * Licensed under the MIT license, which can be read at: http://www.opensource.org/licenses/mit-license.php
+ * @author hd@onlinecity.dk
+ */
+class SocketTransport
+{
+ protected $socket;
+ protected $hosts;
+ protected $persist;
+ protected $debugHandler;
+ public $debug;
+
+ protected static $defaultSendTimeout=100;
+ protected static $defaultRecvTimeout=750;
+ public static $defaultDebug=false;
+
+ public static $forceIpv6=false;
+ public static $forceIpv4=false;
+ public static $randomHost=false;
+
+ /**
+ * Construct a new socket for this transport to use.
+ *
+ * @param array $hosts list of hosts to try.
+ * @param mixed $ports list of ports to try, or a single common port
+ * @param boolean $persist use persistent sockets
+ * @param mixed $debugHandler callback for debug info
+ */
+ public function __construct(array $hosts,$ports,$persist=false,$debugHandler=null)
+ {
+ $this->debug = self::$defaultDebug;
+ $this->debugHandler = $debugHandler ?: 'error_log';
+
+ // Deal with optional port
+ $h = array();
+ foreach ($hosts as $key => $host) {
+ $h[] = array($host, is_array($ports) ? $ports[$key] : $ports);
+ }
+ if (self::$randomHost) shuffle($h);
+ $this->resolveHosts($h);
+
+ $this->persist = $persist;
+ }
+
+ /**
+ * Resolve the hostnames into IPs, and sort them into IPv4 or IPv6 groups.
+ * If using DNS hostnames, and all lookups fail, a InvalidArgumentException is thrown.
+ *
+ * @param array $hosts
+ * @throws InvalidArgumentException
+ */
+ protected function resolveHosts($hosts)
+ {
+ $i = 0;
+ foreach($hosts as $host) {
+ list($hostname,$port) = $host;
+ $ip4s = array();
+ $ip6s = array();
+ if (preg_match('/^([12]?[0-5]?[0-9]\.){3}([12]?[0-5]?[0-9])$/',$hostname)) {
+ // IPv4 address
+ $ip4s[] = $hostname;
+ } else if (preg_match('/^([0-9a-f:]+):[0-9a-f]{1,4}$/i',$hostname)) {
+ // IPv6 address
+ $ip6s[] = hostname;
+ } else { // Do a DNS lookup
+ if (!self::$forceIpv4) {
+ // if not in IPv4 only mode, check the AAAA records first
+ $records = dns_get_record($hostname,DNS_AAAA);
+ if ($records === false && $this->debug) call_user_func($this->debugHandler, 'DNS lookup for AAAA records for: '.$hostname.' failed');
+ if ($records) {
+ foreach ($records as $r) {
+ if (isset($r['ipv6']) && $r['ipv6']) $ip6s[] = $r['ipv6'];
+ }
+ }
+ if ($this->debug) call_user_func($this->debugHandler, "IPv6 addresses for $hostname: ".implode(', ',$ip6s));
+ }
+ if (!self::$forceIpv6) {
+ // if not in IPv6 mode check the A records also
+ $records = dns_get_record($hostname,DNS_A);
+ if ($records === false && $this->debug) call_user_func($this->debugHandler, 'DNS lookup for A records for: '.$hostname.' failed');
+ if ($records) {
+ foreach ($records as $r) {
+ if (isset($r['ip']) && $r['ip']) $ip4s[] = $r['ip'];
+ }
+ }
+ // also try gethostbyname, since name could also be something else, such as "localhost" etc.
+ $ip = gethostbyname($hostname);
+ if (!in_array($ip,$ip4s)) $ip4s[] = $ip;
+ if ($this->debug) call_user_func($this->debugHandler, "IPv4 addresses for $hostname: ".implode(', ',$ip4s));
+ }
+ }
+
+ // Did we get any results?
+ if (self::$forceIpv4 && empty($ip4s)) continue;
+ if (self::$forceIpv6 && empty($ip6s)) continue;
+ if (empty($ip4s) && empty($ip6s)) continue;
+
+ if ($this->debug) $i += count($ip4s)+count($ip6s);
+
+ // Add results to pool
+ $this->hosts[] = array($hostname,$port,$ip6s,$ip4s);
+ }
+ if ($this->debug) call_user_func($this->debugHandler, "Built connection pool of ".count($this->hosts)." host(s) with $i ip(s) in total");
+ if (empty($this->hosts)) throw new InvalidArgumentException('No valid hosts was found');
+ }
+
+ /**
+ * Get a reference to the socket.
+ * You should use the public functions rather than the socket directly
+ */
+ public function getSocket()
+ {
+ return $this->socket;
+ }
+
+ /**
+ * Get an arbitrary option
+ *
+ * @param integer $option
+ * @param integer $lvl
+ */
+ public function getSocketOption($option,$lvl=SOL_SOCKET)
+ {
+ return socket_get_option($this->socket,$lvl,$option);
+ }
+
+ /**
+ * Set an arbitrary option
+ *
+ * @param integer $option
+ * @param mixed $value
+ * @param integer $lvl
+ */
+ public function setSocketOption($option,$value,$lvl=SOL_SOCKET)
+ {
+ return socket_set_option($this->socket,$lvl,$option,$value);
+ }
+
+ /**
+ * Sets the send timeout.
+ * Returns true on success, or false.
+ * @param int $timeout Timeout in milliseconds.
+ * @return boolean
+ */
+ public function setSendTimeout($timeout)
+ {
+ if (!$this->isOpen()) {
+ self::$defaultSendTimeout = $timeout;
+ } else {
+ $r = socket_set_option($this->socket,SOL_SOCKET,SO_SNDTIMEO,$this->millisecToSolArray($timeout));
+ return $r;
+ }
+ }
+
+ /**
+ * Sets the receive timeout.
+ * Returns true on success, or false.
+ * @param int $timeout Timeout in milliseconds.
+ * @return boolean
+ */
+ public function setRecvTimeout($timeout)
+ {
+ if (!$this->isOpen()) {
+ self::$defaultRecvTimeout = $timeout;
+ } else {
+ $r = socket_set_option($this->socket,SOL_SOCKET,SO_RCVTIMEO,$this->millisecToSolArray($timeout));
+ return $r;
+ }
+ }
+
+ /**
+ * Check if the socket is constructed, and there are no exceptions on it
+ * Returns false if it's closed.
+ * Throws SocketTransportException is state could not be ascertained
+ * @throws SocketTransportException
+ */
+ public function isOpen()
+ {
+ if (!is_resource($this->socket)) return false;
+ $r = null;
+ $w = null;
+ $e = array($this->socket);
+ $res = socket_select($r,$w,$e,0);
+ if ($res === false) throw new SocketTransportException('Could not examine socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ if (!empty($e)) return false; // if there is an exception on our socket it's probably dead
+ return true;
+ }
+
+ /**
+ * Convert a milliseconds into a socket sec+usec array
+ * @param integer $millisec
+ * @return array
+ */
+ private function millisecToSolArray($millisec)
+ {
+ $usec = $millisec*1000;
+ return array('sec' => floor($usec/1000000), 'usec' => $usec%1000000);
+ }
+
+ /**
+ * Open the socket, trying to connect to each host in succession.
+ * This will prefer IPv6 connections if forceIpv4 is not enabled.
+ * If all hosts fail, a SocketTransportException is thrown.
+ *
+ * @throws SocketTransportException
+ */
+ public function open()
+ {
+ if (!self::$forceIpv4) {
+ $socket6 = @socket_create(AF_INET6,SOCK_STREAM,SOL_TCP);
+ if ($socket6 == false) throw new SocketTransportException('Could not create socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ socket_set_option($socket6,SOL_SOCKET,SO_SNDTIMEO,$this->millisecToSolArray(self::$defaultSendTimeout));
+ socket_set_option($socket6,SOL_SOCKET,SO_RCVTIMEO,$this->millisecToSolArray(self::$defaultRecvTimeout));
+ }
+ if (!self::$forceIpv6) {
+ $socket4 = @socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
+ if ($socket4 == false) throw new SocketTransportException('Could not create socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ socket_set_option($socket4,SOL_SOCKET,SO_SNDTIMEO,$this->millisecToSolArray(self::$defaultSendTimeout));
+ socket_set_option($socket4,SOL_SOCKET,SO_RCVTIMEO,$this->millisecToSolArray(self::$defaultRecvTimeout));
+ }
+ $it = new ArrayIterator($this->hosts);
+ while ($it->valid()) {
+ list($hostname,$port,$ip6s,$ip4s) = $it->current();
+ if (!self::$forceIpv4 && !empty($ip6s)) { // Attempt IPv6s first
+ foreach ($ip6s as $ip) {
+ if ($this->debug) call_user_func($this->debugHandler, "Connecting to $ip:$port...");
+ $r = socket_connect($socket6, $ip, $port);
+ if ($r) {
+ if ($this->debug) call_user_func($this->debugHandler, "Connected to $ip:$port!");
+ @socket_close($socket4);
+ $this->socket = $socket6;
+ return;
+ } elseif ($this->debug) {
+ call_user_func($this->debugHandler, "Socket connect to $ip:$port failed; ".socket_strerror(socket_last_error()));
+ }
+ }
+ }
+ if (!self::$forceIpv6 && !empty($ip4s)) {
+ foreach ($ip4s as $ip) {
+ if ($this->debug) call_user_func($this->debugHandler, "Connecting to $ip:$port...");
+ $r = socket_connect($socket4, $ip, $port);
+ if ($r) {
+ if ($this->debug) call_user_func($this->debugHandler, "Connected to $ip:$port!");
+ @socket_close($socket6);
+ $this->socket = $socket4;
+ return;
+ } elseif ($this->debug) {
+ call_user_func($this->debugHandler, "Socket connect to $ip:$port failed; ".socket_strerror(socket_last_error()));
+ }
+ }
+ }
+ $it->next();
+ }
+ throw new SocketTransportException('Could not connect to any of the specified hosts');
+ }
+
+ /**
+ * Do a clean shutdown of the socket.
+ * Since we don't reuse sockets, we can just close and forget about it,
+ * but we choose to wait (linger) for the last data to come through.
+ */
+ public function close()
+ {
+ $arrOpt = array('l_onoff' => 1, 'l_linger' => 1);
+ socket_set_block($this->socket);
+ socket_set_option($this->socket, SOL_SOCKET, SO_LINGER, $arrOpt);
+ socket_close($this->socket);
+ }
+
+ /**
+ * Check if there is data waiting for us on the wire
+ * @return boolean
+ * @throws SocketTransportException
+ */
+ public function hasData()
+ {
+ $r = array($this->socket);
+ $w = null;
+ $e = null;
+ $res = socket_select($r,$w,$e,0);
+ if ($res === false) throw new SocketTransportException('Could not examine socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ if (!empty($r)) return true;
+ return false;
+ }
+
+ /**
+ * Read up to $length bytes from the socket.
+ * Does not guarantee that all the bytes are read.
+ * Returns false on EOF
+ * Returns false on timeout (technically EAGAIN error).
+ * Throws SocketTransportException if data could not be read.
+ *
+ * @param integer $length
+ * @return mixed
+ * @throws SocketTransportException
+ */
+ public function read($length)
+ {
+ $d = socket_read($this->socket,$length,PHP_BINARY_READ);
+ if ($d === false && socket_last_error() === 11) return false; // sockets give 11 (EAGAIN) on timeout
+ if ($d === false) throw new SocketTransportException('Could not read '.$length.' bytes from socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ if ($d === '') return false;
+ return $d;
+ }
+
+ /**
+ * Read all the bytes, and block until they are read.
+ * Timeout throws SocketTransportException
+ *
+ * @param integer $length
+ */
+ public function readAll($length)
+ {
+ $d = "";
+ $r = 0;
+ $readTimeout = socket_get_option($this->socket,SOL_SOCKET,SO_RCVTIMEO);
+ while ($r < $length) {
+ $buf = '';
+ $r += socket_recv($this->socket,$buf,$length-$r,MSG_DONTWAIT);
+ if ($r === false) throw new SocketTransportException('Could not read '.$length.' bytes from socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ $d .= $buf;
+ if ($r == $length) return $d;
+
+ // wait for data to be available, up to timeout
+ $r = array($this->socket);
+ $w = null;
+ $e = array($this->socket);
+ $res = socket_select($r,$w,$e,$readTimeout['sec'],$readTimeout['usec']);
+
+ // check
+ if ($res === false) throw new SocketTransportException('Could not examine socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ if (!empty($e)) throw new SocketTransportException('Socket exception while waiting for data; '.socket_strerror(socket_last_error()), socket_last_error());
+ if (empty($r)) throw new SocketTransportException('Timed out waiting for data on socket');
+ }
+ }
+
+ /**
+ * Write (all) data to the socket.
+ * Timeout throws SocketTransportException
+ *
+ * @param integer $length
+ */
+ public function write($buffer,$length)
+ {
+ $r = $length;
+ $writeTimeout = socket_get_option($this->socket,SOL_SOCKET,SO_SNDTIMEO);
+
+ while ($r>0) {
+ $wrote = socket_write($this->socket,$buffer,$r);
+ if ($wrote === false) throw new SocketTransportException('Could not write '.$length.' bytes to socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ $r -= $wrote;
+ if ($r == 0) return;
+
+ $buffer = substr($buffer,$wrote);
+
+ // wait for the socket to accept more data, up to timeout
+ $r = null;
+ $w = array($this->socket);
+ $e = array($this->socket);
+ $res = socket_select($r,$w,$e,$writeTimeout['sec'],$writeTimeout['usec']);
+
+ // check
+ if ($res === false) throw new SocketTransportException('Could not examine socket; '.socket_strerror(socket_last_error()), socket_last_error());
+ if (!empty($e)) throw new SocketTransportException('Socket exception while waiting to write data; '.socket_strerror(socket_last_error()), socket_last_error());
+ if (empty($w)) throw new SocketTransportException('Timed out waiting to write data on socket');
+ }
+ }
+}
+
+class SocketTransportException extends RuntimeException { } \ No newline at end of file
diff --git a/transport/LICENSE b/transport/LICENSE
deleted file mode 100644
index 9d189ef..0000000
--- a/transport/LICENSE
+++ /dev/null
@@ -1,324 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
---------------------------------------------------
-SOFTWARE DISTRIBUTED WITH THRIFT:
-
-The Apache Thrift software includes a number of subcomponents with
-separate copyright notices and license terms. Your use of the source
-code for the these subcomponents is subject to the terms and
-conditions of the following licenses.
-
---------------------------------------------------
-Portions of the following files are licensed under the MIT License:
-
- lib/erl/src/Makefile.am
-
-Please see doc/otp-base-license.txt for the full terms of this license.
-
-
---------------------------------------------------
-The following files contain some portions of code contributed under
-the Thrift Software License (see doc/old-thrift-license.txt), and relicensed
-under the Apache 2.0 License:
-
- compiler/cpp/Makefile.am
- compiler/cpp/src/generate/t_cocoa_generator.cc
- compiler/cpp/src/generate/t_cpp_generator.cc
- compiler/cpp/src/generate/t_csharp_generator.cc
- compiler/cpp/src/generate/t_erl_generator.cc
- compiler/cpp/src/generate/t_hs_generator.cc
- compiler/cpp/src/generate/t_java_generator.cc
- compiler/cpp/src/generate/t_ocaml_generator.cc
- compiler/cpp/src/generate/t_perl_generator.cc
- compiler/cpp/src/generate/t_php_generator.cc
- compiler/cpp/src/generate/t_py_generator.cc
- compiler/cpp/src/generate/t_rb_generator.cc
- compiler/cpp/src/generate/t_st_generator.cc
- compiler/cpp/src/generate/t_xsd_generator.cc
- compiler/cpp/src/main.cc
- compiler/cpp/src/parse/t_field.h
- compiler/cpp/src/parse/t_program.h
- compiler/cpp/src/platform.h
- compiler/cpp/src/thriftl.ll
- compiler/cpp/src/thrifty.yy
- lib/csharp/src/Protocol/TBinaryProtocol.cs
- lib/csharp/src/Protocol/TField.cs
- lib/csharp/src/Protocol/TList.cs
- lib/csharp/src/Protocol/TMap.cs
- lib/csharp/src/Protocol/TMessage.cs
- lib/csharp/src/Protocol/TMessageType.cs
- lib/csharp/src/Protocol/TProtocol.cs
- lib/csharp/src/Protocol/TProtocolException.cs
- lib/csharp/src/Protocol/TProtocolFactory.cs
- lib/csharp/src/Protocol/TProtocolUtil.cs
- lib/csharp/src/Protocol/TSet.cs
- lib/csharp/src/Protocol/TStruct.cs
- lib/csharp/src/Protocol/TType.cs
- lib/csharp/src/Server/TServer.cs
- lib/csharp/src/Server/TSimpleServer.cs
- lib/csharp/src/Server/TThreadPoolServer.cs
- lib/csharp/src/TApplicationException.cs
- lib/csharp/src/Thrift.csproj
- lib/csharp/src/Thrift.sln
- lib/csharp/src/TProcessor.cs
- lib/csharp/src/Transport/TServerSocket.cs
- lib/csharp/src/Transport/TServerTransport.cs
- lib/csharp/src/Transport/TSocket.cs
- lib/csharp/src/Transport/TStreamTransport.cs
- lib/csharp/src/Transport/TTransport.cs
- lib/csharp/src/Transport/TTransportException.cs
- lib/csharp/src/Transport/TTransportFactory.cs
- lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs
- lib/csharp/ThriftMSBuildTask/ThriftBuild.cs
- lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj
- lib/rb/lib/thrift.rb
- lib/st/README
- lib/st/thrift.st
- test/OptionalRequiredTest.cpp
- test/OptionalRequiredTest.thrift
- test/ThriftTest.thrift
-
---------------------------------------------------
-For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components:
-
-# Copyright (c) 2007 Thomas Porschberg <thomas@randspringer.de>
-#
-# Copying and distribution of this file, with or without
-# modification, are permitted in any medium without royalty provided
-# the copyright notice and this notice are preserved.
-
---------------------------------------------------
-For the compiler/cpp/src/md5.[ch] components:
-
-/*
- Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-
----------------------------------------------------
-For the lib/rb/setup.rb: Copyright (c) 2000-2005 Minero Aoki,
-lib/ocaml/OCamlMakefile and lib/ocaml/README-OCamlMakefile components:
- Copyright (C) 1999 - 2007 Markus Mottl
-
-Licensed under the terms of the GNU Lesser General Public License 2.1
-(see doc/lgpl-2.1.txt for the full terms of this license)
diff --git a/transport/texception.class.php b/transport/texception.class.php
deleted file mode 100644
index 10548fa..0000000
--- a/transport/texception.class.php
+++ /dev/null
@@ -1,2 +0,0 @@
-<?php
-class TException extends Exception { }; \ No newline at end of file
diff --git a/transport/tsocket.class.php b/transport/tsocket.class.php
deleted file mode 100644
index 8a3b101..0000000
--- a/transport/tsocket.class.php
+++ /dev/null
@@ -1,331 +0,0 @@
-<?php
-require_once $GLOBALS['SMPP_ROOT'].'/transport/ttransport.class.php';
-require_once $GLOBALS['SMPP_ROOT'].'/transport/texception.class.php';
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @package thrift.transport
- */
-
-/**
- * Sockets implementation of the TTransport interface.
- *
- * @package thrift.transport
- */
-class TSocket extends TTransport {
-
- /**
- * Handle to PHP socket
- *
- * @var resource
- */
- private $handle_ = null;
-
- /**
- * Remote hostname
- *
- * @var string
- */
- protected $host_ = 'localhost';
-
- /**
- * Remote port
- *
- * @var int
- */
- protected $port_ = '9090';
-
- /**
- * Send timeout in milliseconds
- *
- * @var int
- */
- private $sendTimeout_ = 100;
-
- /**
- * Recv timeout in milliseconds
- *
- * @var int
- */
- private $recvTimeout_ = 750;
-
- /**
- * Is send timeout set?
- *
- * @var bool
- */
- private $sendTimeoutSet_ = FALSE;
-
- /**
- * Persistent socket or plain?
- *
- * @var bool
- */
- private $persist_ = FALSE;
-
- /**
- * Debugging on?
- *
- * @var bool
- */
- protected $debug_ = FALSE;
-
- /**
- * Debug handler
- *
- * @var mixed
- */
- protected $debugHandler_ = null;
-
- /**
- * Socket constructor
- *
- * @param string $host Remote hostname
- * @param int $port Remote port
- * @param bool $persist Whether to use a persistent socket
- * @param string $debugHandler Function to call for error logging
- */
- public function __construct($host='localhost',
- $port=9090,
- $persist=FALSE,
- $debugHandler=null) {
- $this->host_ = $host;
- $this->port_ = $port;
- $this->persist_ = $persist;
- $this->debugHandler_ = $debugHandler ? $debugHandler : 'error_log';
- }
-
- /**
- * @param resource $handle
- * @return void
- */
- public function setHandle($handle) {
- $this->handle_ = $handle;
- }
-
- /**
- * Sets the send timeout.
- *
- * @param int $timeout Timeout in milliseconds.
- */
- public function setSendTimeout($timeout) {
- $this->sendTimeout_ = $timeout;
- }
-
- /**
- * Sets the receive timeout.
- *
- * @param int $timeout Timeout in milliseconds.
- */
- public function setRecvTimeout($timeout) {
- $this->recvTimeout_ = $timeout;
- }
-
- /**
- * Sets debugging output on or off
- *
- * @param bool $debug
- */
- public function setDebug($debug) {
- $this->debug_ = $debug;
- }
-
- /**
- * Get the host that this socket is connected to
- *
- * @return string host
- */
- public function getHost() {
- return $this->host_;
- }
-
- /**
- * Get the remote port that this socket is connected to
- *
- * @return int port
- */
- public function getPort() {
- return $this->port_;
- }
-
- /**
- * Tests whether this is open
- *
- * @return bool true if the socket is open
- */
- public function isOpen() {
- return is_resource($this->handle_);
- }
-
- /**
- * 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_,
- $this->port_,
- $errno,
- $errstr,
- $this->sendTimeout_/1000.0);
- } else {
- $this->handle_ = @fsockopen($this->host_,
- $this->port_,
- $errno,
- $errstr,
- $this->sendTimeout_/1000.0);
- }
-
- // Connect failed?
- if ($this->handle_ === FALSE) {
- $error = 'TSocket: Could not connect to '.$this->host_.':'.$this->port_.' ('.$errstr.' ['.$errno.'])';
- if ($this->debug_) {
- call_user_func($this->debugHandler_, $error);
- }
- throw new TException($error);
- }
-
- stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
- $this->sendTimeoutSet_ = TRUE;
- }
-
- /**
- * Closes the socket.
- */
- public function close() {
- if (!$this->persist_) {
- @fclose($this->handle_);
- $this->handle_ = null;
- }
- }
-
- /**
- * Uses stream get contents to do the reading
- *
- * @param int $len How many bytes
- * @return string Binary data
- */
- public function readAll($len) {
- if ($this->sendTimeoutSet_) {
- stream_set_timeout($this->handle_, 0, $this->recvTimeout_*1000);
- $this->sendTimeoutSet_ = FALSE;
- }
- // This call does not obey stream_set_timeout values!
- // $buf = @stream_get_contents($this->handle_, $len);
-
- $pre = null;
- while (TRUE) {
- $buf = @fread($this->handle_, $len);
- if ($buf === FALSE) {
- $md = stream_get_meta_data($this->handle_);
- if (true === $md['timed_out'] && false === $md['blocked']) {
- throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
- } else {
- 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 (true === $md['timed_out'] && false === $md['blocked']) {
- throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
- } else {
- $pre .= $buf;
- $len -= $sz;
- }
- } else {
- return $pre.$buf;
- }
- }
- }
-
- /**
- * Read from the socket
- *
- * @param int $len How many bytes
- * @return string Binary data
- */
- public function read($len) {
- if ($this->sendTimeoutSet_) {
- stream_set_timeout($this->handle_, 0, $this->recvTimeout_*1000);
- $this->sendTimeoutSet_ = FALSE;
- }
- $data = @fread($this->handle_, $len);
- if ($data === FALSE) {
- $md = stream_get_meta_data($this->handle_);
- if (true === $md['timed_out'] && false === $md['blocked']) {
- throw new TTransportException('TSocket: timed out reading '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
- } else {
- throw new TTransportException('TSocket: Could not read '.$len.' bytes from '.
- $this->host_.':'.$this->port_);
- }
- }
- return $data;
- }
-
- /**
- * Write to the socket.
- *
- * @param string $buf The data to write
- */
- public function write($buf) {
- if (!$this->sendTimeoutSet_) {
- stream_set_timeout($this->handle_, 0, $this->sendTimeout_*1000);
- $this->sendTimeoutSet_ = TRUE;
- }
- while (strlen($buf) > 0) {
- $got = @fwrite($this->handle_, $buf);
- if ($got === 0 || $got === FALSE) {
- $md = stream_get_meta_data($this->handle_);
- if ($md['timed_out']) {
- throw new TTransportException('TSocket: timed out writing '.strlen($buf).' bytes from '.
- $this->host_.':'.$this->port_);
- } else {
- throw new TTransportException('TSocket: Could not write '.strlen($buf).' bytes '.
- $this->host_.':'.$this->port_);
- }
- }
- $buf = substr($buf, $got);
- }
- }
-
- /**
- * Flush output to the socket.
- */
- public function flush() {
- $ret = fflush($this->handle_);
- if ($ret === FALSE) {
- throw new TException('TSocket: Could not flush: '.
- $this->host_.':'.$this->port_);
- }
- }
-}
diff --git a/transport/tsocketpool.class.php b/transport/tsocketpool.class.php
deleted file mode 100644
index e254787..0000000
--- a/transport/tsocketpool.class.php
+++ /dev/null
@@ -1,294 +0,0 @@
-<?php
-require_once $GLOBALS['SMPP_ROOT'].'/transport/tsocket.class.php';
-require_once $GLOBALS['SMPP_ROOT'].'/transport/texception.class.php';
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @package thrift.transport
- */
-
-
-/**
- * This library makes use of APC cache to make hosts as down in a web
- * environment. If you are running from the CLI or on a system without APC
- * installed, then these null functions will step in and act like cache
- * misses.
- */
-if (!function_exists('apc_fetch')) {
- function apc_fetch($key) { return FALSE; }
- function apc_store($key, $var, $ttl=0) { return FALSE; }
-}
-
-/**
- * Sockets implementation of the TTransport interface that allows connection
- * to a pool of servers.
- *
- * @package thrift.transport
- */
-class TSocketPool extends TSocket {
-
- /**
- * Remote servers. Array of associative arrays with 'host' and 'port' keys
- */
- private $servers_ = array();
-
- /**
- * How many times to retry each host in connect
- *
- * @var int
- */
- private $numRetries_ = 1;
-
- /**
- * Retry interval in seconds, how long to not try a host if it has been
- * marked as down.
- *
- * @var int
- */
- private $retryInterval_ = 60;
-
- /**
- * Max consecutive failures before marking a host down.
- *
- * @var int
- */
- private $maxConsecutiveFailures_ = 1;
-
- /**
- * Try hosts in order? or Randomized?
- *
- * @var bool
- */
- private $randomize_ = TRUE;
-
- /**
- * Always try last host, even if marked down?
- *
- * @var bool
- */
- private $alwaysTryLast_ = TRUE;
-
- /**
- * Socket pool constructor
- *
- * @param array $hosts List of remote hostnames
- * @param mixed $ports Array of remote ports, or a single common port
- * @param bool $persist Whether to use a persistent socket
- * @param mixed $debugHandler Function for error logging
- */
- public function __construct($hosts=array('localhost'),
- $ports=array(9090),
- $persist=FALSE,
- $debugHandler=null) {
- parent::__construct(null, 0, $persist, $debugHandler);
-
- if (!is_array($ports)) {
- $port = $ports;
- $ports = array();
- foreach ($hosts as $key => $val) {
- $ports[$key] = $port;
- }
- }
-
- foreach ($hosts as $key => $host) {
- $this->servers_ []= array('host' => $host,
- 'port' => $ports[$key]);
- }
- }
-
- /**
- * Add a server to the pool
- *
- * This function does not prevent you from adding a duplicate server entry.
- *
- * @param string $host hostname or IP
- * @param int $port port
- */
- public function addServer($host, $port) {
- $this->servers_[] = array('host' => $host, 'port' => $port);
- }
-
- /**
- * Sets how many time to keep retrying a host in the connect function.
- *
- * @param int $numRetries
- */
- public function setNumRetries($numRetries) {
- $this->numRetries_ = $numRetries;
- }
-
- /**
- * Sets how long to wait until retrying a host if it was marked down
- *
- * @param int $numRetries
- */
- public function setRetryInterval($retryInterval) {
- $this->retryInterval_ = $retryInterval;
- }
-
- /**
- * Sets how many time to keep retrying a host before marking it as down.
- *
- * @param int $numRetries
- */
- public function setMaxConsecutiveFailures($maxConsecutiveFailures) {
- $this->maxConsecutiveFailures_ = $maxConsecutiveFailures;
- }
-
- /**
- * Turns randomization in connect order on or off.
- *
- * @param bool $randomize
- */
- public function setRandomize($randomize) {
- $this->randomize_ = $randomize;
- }
-
- /**
- * Whether to always try the last server.
- *
- * @param bool $alwaysTryLast
- */
- public function setAlwaysTryLast($alwaysTryLast) {
- $this->alwaysTryLast_ = $alwaysTryLast;
- }
-
-
- /**
- * Connects the socket by iterating through all the servers in the pool
- * and trying to find one that works.
- */
- public function open() {
- // Check if we want order randomization
- if ($this->randomize_) {
- shuffle($this->servers_);
- }
-
- // Count servers to identify the "last" one
- $numServers = count($this->servers_);
-
- for ($i = 0; $i < $numServers; ++$i) {
-
- // This extracts the $host and $port variables
- extract($this->servers_[$i]);
-
- // Check APC cache for a record of this server being down
- $failtimeKey = 'thrift_failtime:'.$host.':'.$port.'~';
-
- // Cache miss? Assume it's OK
- $lastFailtime = apc_fetch($failtimeKey);
- if ($lastFailtime === FALSE) {
- $lastFailtime = 0;
- }
-
- $retryIntervalPassed = FALSE;
-
- // Cache hit...make sure enough the retry interval has elapsed
- if ($lastFailtime > 0) {
- $elapsed = time() - $lastFailtime;
- if ($elapsed > $this->retryInterval_) {
- $retryIntervalPassed = TRUE;
- if ($this->debug_) {
- call_user_func($this->debugHandler_,
- 'TSocketPool: retryInterval '.
- '('.$this->retryInterval_.') '.
- 'has passed for host '.$host.':'.$port);
- }
- }
- }
-
- // Only connect if not in the middle of a fail interval, OR if this
- // is the LAST server we are trying, just hammer away on it
- $isLastServer = FALSE;
- if ($this->alwaysTryLast_) {
- $isLastServer = ($i == ($numServers - 1));
- }
-
- if (($lastFailtime === 0) ||
- ($isLastServer) ||
- ($lastFailtime > 0 && $retryIntervalPassed)) {
-
- // Set underlying TSocket params to this one
- $this->host_ = $host;
- $this->port_ = $port;
-
- // Try up to numRetries_ connections per server
- for ($attempt = 0; $attempt < $this->numRetries_; $attempt++) {
- try {
- // Use the underlying TSocket open function
- parent::open();
-
- // Only clear the failure counts if required to do so
- if ($lastFailtime > 0) {
- apc_store($failtimeKey, 0);
- }
-
- // Successful connection, return now
- return;
-
- } catch (TException $tx) {
- // Connection failed
- }
- }
-
- // Mark failure of this host in the cache
- $consecfailsKey = 'thrift_consecfails:'.$host.':'.$port.'~';
-
- // Ignore cache misses
- $consecfails = apc_fetch($consecfailsKey);
- if ($consecfails === FALSE) {
- $consecfails = 0;
- }
-
- // Increment by one
- $consecfails++;
-
- // Log and cache this failure
- if ($consecfails >= $this->maxConsecutiveFailures_) {
- if ($this->debug_) {
- call_user_func($this->debugHandler_,
- 'TSocketPool: marking '.$host.':'.$port.
- ' as down for '.$this->retryInterval_.' secs '.
- 'after '.$consecfails.' failed attempts.');
- }
- // Store the failure time
- apc_store($failtimeKey, time());
-
- // Clear the count of consecutive failures
- apc_store($consecfailsKey, 0);
- } else {
- apc_store($consecfailsKey, $consecfails);
- }
- }
- }
-
- // Oh no; we failed them all. The system is totally ill!
- $error = 'TSocketPool: All hosts in pool are down. ';
- $hosts = array();
- foreach ($this->servers_ as $server) {
- $hosts []= $server['host'].':'.$server['port'];
- }
- $hostlist = implode(',', $hosts);
- $error .= '('.$hostlist.')';
- if ($this->debug_) {
- call_user_func($this->debugHandler_, $error);
- }
- throw new TException($error);
- }
-}
diff --git a/transport/ttransport.class.php b/transport/ttransport.class.php
deleted file mode 100644
index a387f13..0000000
--- a/transport/ttransport.class.php
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-require_once $GLOBALS['SMPP_ROOT'].'/transport/texception.class.php';
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- * @package thrift.transport
- */
-
-
-/**
- * Transport exceptions
- */
-class TTransportException extends TException {
-
- const UNKNOWN = 0;
- const NOT_OPEN = 1;
- const ALREADY_OPEN = 2;
- const TIMED_OUT = 3;
- const END_OF_FILE = 4;
-
- function __construct($message=null, $code=0) {
- parent::__construct($message, $code);
- }
-}
-
-/**
- * Base interface for a transport agent.
- *
- * @package thrift.transport
- */
-abstract class TTransport {
-
- /**
- * Whether this transport is open.
- *
- * @return boolean true if open
- */
- public abstract function isOpen();
-
- /**
- * Open the transport for reading/writing
- *
- * @throws TTransportException if cannot open
- */
- public abstract function open();
-
- /**
- * Close the transport.
- */
- public abstract function close();
-
- /**
- * Read some data into the array.
- *
- * @param int $len How much to read
- * @return string The data that has been read
- * @throws TTransportException if cannot read any more data
- */
- public abstract function read($len);
-
- /**
- * Guarantees that the full amount of data is read.
- *
- * @return string The data, of exact length
- * @throws TTransportException if cannot read data
- */
- public function readAll($len) {
- // return $this->read($len);
-
- $data = '';
- $got = 0;
- while (($got = strlen($data)) < $len) {
- $data .= $this->read($len - $got);
- }
- return $data;
- }
-
- /**
- * Writes the given data out.
- *
- * @param string $buf The data to write
- * @throws TTransportException if writing fails
- */
- public abstract function write($buf);
-
- /**
- * Flushes any pending data out of a buffer
- *
- * @throws TTransportException if a writing error occurs
- */
- public function flush() {}
-}