diff options
author | Hans Duedal <hd@onlinecity.dk> | 2011-07-22 20:14:40 +0200 |
---|---|---|
committer | Hans Duedal <hd@onlinecity.dk> | 2011-07-22 20:14:40 +0200 |
commit | 3d1329a02f3f8bf08df4ddb4b7929d4574efed24 (patch) | |
tree | 656eb4ba776b95f855418f4a663d4649e3ca60da | |
parent | 61c99fc84e22696a84b45661ac223dfb5911e849 (diff) | |
download | php-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.md | 23 | ||||
-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.php | 378 | ||||
-rw-r--r-- | transport/LICENSE | 324 | ||||
-rw-r--r-- | transport/texception.class.php | 2 | ||||
-rw-r--r-- | transport/tsocket.class.php | 331 | ||||
-rw-r--r-- | transport/tsocketpool.class.php | 294 | ||||
-rw-r--r-- | transport/ttransport.class.php | 108 |
9 files changed, 424 insertions, 1075 deletions
@@ -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() {} -} |