1<?php 2/** 3 * This file is part of the FreeDSx Socket package. 4 * 5 * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11namespace FreeDSx\Socket; 12 13use FreeDSx\Socket\Exception\ConnectionException; 14 15/** 16 * Given a selection of hosts, connect to one and return the TCP Socket. 17 * 18 * @author Chad Sikorra <Chad.Sikorra@gmail.com> 19 */ 20class SocketPool 21{ 22 /** 23 * @var array 24 */ 25 protected $options = [ 26 'servers' => [], 27 'port' => 389, 28 'timeout_connect' => 1, 29 ]; 30 31 /** 32 * @var array 33 */ 34 protected $tcpOpts = [ 35 'use_ssl', 36 'ssl_validate_cert', 37 'ssl_allow_self_signed', 38 'ssl_ca_cert', 39 'ssl_cert', 40 'ssl_peer_name', 41 'timeout_connect', 42 'timeout_read', 43 'port', 44 ]; 45 46 /** 47 * @param array $options 48 */ 49 public function __construct(array $options) 50 { 51 $this->options = \array_merge($this->options, $options); 52 } 53 54 /** 55 * @throws ConnectionException 56 */ 57 public function connect(string $hostname = '') : Socket 58 { 59 $hosts = ($hostname !== '') ? [$hostname] : (array) $this->options['servers']; 60 61 $lastEx = null; 62 $tcp = null; 63 foreach ($hosts as $host) { 64 try { 65 $tcp = Socket::create($host, $this->getTcpOptions()); 66 break; 67 } catch (\Exception $e) { 68 $lastEx = $e; 69 } 70 } 71 72 if ($tcp === null) { 73 throw new ConnectionException(sprintf( 74 'Unable to connect to server(s): %s', 75 implode(',', $hosts) 76 ), 0, $lastEx); 77 } 78 79 return $tcp; 80 } 81 82 /** 83 * @return array 84 */ 85 protected function getTcpOptions() : array 86 { 87 $opts = []; 88 89 foreach ($this->tcpOpts as $name) { 90 if (isset($this->options[$name])) { 91 $opts[$name] = $this->options[$name]; 92 } 93 } 94 95 return $opts; 96 } 97} 98