10b3fd2d3SAndreas Gohr<?php 20b3fd2d3SAndreas Gohr/** 30b3fd2d3SAndreas Gohr * This file is part of the FreeDSx Socket package. 40b3fd2d3SAndreas Gohr * 50b3fd2d3SAndreas Gohr * (c) Chad Sikorra <Chad.Sikorra@gmail.com> 60b3fd2d3SAndreas Gohr * 70b3fd2d3SAndreas Gohr * For the full copyright and license information, please view the LICENSE 80b3fd2d3SAndreas Gohr * file that was distributed with this source code. 90b3fd2d3SAndreas Gohr */ 100b3fd2d3SAndreas Gohr 110b3fd2d3SAndreas Gohrnamespace FreeDSx\Socket; 120b3fd2d3SAndreas Gohr 130b3fd2d3SAndreas Gohruse FreeDSx\Socket\Exception\ConnectionException; 140b3fd2d3SAndreas Gohr 150b3fd2d3SAndreas Gohr/** 16*dad993c5SAndreas Gohr * Given a selection of hosts, connect to one and return the Socket. 170b3fd2d3SAndreas Gohr * 180b3fd2d3SAndreas Gohr * @author Chad Sikorra <Chad.Sikorra@gmail.com> 190b3fd2d3SAndreas Gohr */ 200b3fd2d3SAndreas Gohrclass SocketPool 210b3fd2d3SAndreas Gohr{ 220b3fd2d3SAndreas Gohr /** 230b3fd2d3SAndreas Gohr * @var array 240b3fd2d3SAndreas Gohr */ 250b3fd2d3SAndreas Gohr protected $options = [ 260b3fd2d3SAndreas Gohr 'servers' => [], 270b3fd2d3SAndreas Gohr 'port' => 389, 280b3fd2d3SAndreas Gohr 'timeout_connect' => 1, 290b3fd2d3SAndreas Gohr ]; 300b3fd2d3SAndreas Gohr 310b3fd2d3SAndreas Gohr /** 320b3fd2d3SAndreas Gohr * @var array 330b3fd2d3SAndreas Gohr */ 34*dad993c5SAndreas Gohr protected $socketOpts = [ 350b3fd2d3SAndreas Gohr 'use_ssl', 360b3fd2d3SAndreas Gohr 'ssl_validate_cert', 370b3fd2d3SAndreas Gohr 'ssl_allow_self_signed', 380b3fd2d3SAndreas Gohr 'ssl_ca_cert', 390b3fd2d3SAndreas Gohr 'ssl_cert', 400b3fd2d3SAndreas Gohr 'ssl_peer_name', 410b3fd2d3SAndreas Gohr 'timeout_connect', 420b3fd2d3SAndreas Gohr 'timeout_read', 430b3fd2d3SAndreas Gohr 'port', 44*dad993c5SAndreas Gohr 'transport', 450b3fd2d3SAndreas Gohr ]; 460b3fd2d3SAndreas Gohr 470b3fd2d3SAndreas Gohr /** 480b3fd2d3SAndreas Gohr * @param array $options 490b3fd2d3SAndreas Gohr */ 500b3fd2d3SAndreas Gohr public function __construct(array $options) 510b3fd2d3SAndreas Gohr { 520b3fd2d3SAndreas Gohr $this->options = \array_merge($this->options, $options); 530b3fd2d3SAndreas Gohr } 540b3fd2d3SAndreas Gohr 550b3fd2d3SAndreas Gohr /** 560b3fd2d3SAndreas Gohr * @throws ConnectionException 570b3fd2d3SAndreas Gohr */ 580b3fd2d3SAndreas Gohr public function connect(string $hostname = '') : Socket 590b3fd2d3SAndreas Gohr { 600b3fd2d3SAndreas Gohr $hosts = ($hostname !== '') ? [$hostname] : (array) $this->options['servers']; 610b3fd2d3SAndreas Gohr 620b3fd2d3SAndreas Gohr $lastEx = null; 63*dad993c5SAndreas Gohr $socket = null; 640b3fd2d3SAndreas Gohr foreach ($hosts as $host) { 650b3fd2d3SAndreas Gohr try { 66*dad993c5SAndreas Gohr $socket = Socket::create( 67*dad993c5SAndreas Gohr $host, 68*dad993c5SAndreas Gohr $this->getSocketOptions() 69*dad993c5SAndreas Gohr ); 700b3fd2d3SAndreas Gohr break; 710b3fd2d3SAndreas Gohr } catch (\Exception $e) { 720b3fd2d3SAndreas Gohr $lastEx = $e; 730b3fd2d3SAndreas Gohr } 740b3fd2d3SAndreas Gohr } 750b3fd2d3SAndreas Gohr 76*dad993c5SAndreas Gohr if ($socket === null) { 770b3fd2d3SAndreas Gohr throw new ConnectionException(sprintf( 780b3fd2d3SAndreas Gohr 'Unable to connect to server(s): %s', 790b3fd2d3SAndreas Gohr implode(',', $hosts) 800b3fd2d3SAndreas Gohr ), 0, $lastEx); 810b3fd2d3SAndreas Gohr } 820b3fd2d3SAndreas Gohr 83*dad993c5SAndreas Gohr return $socket; 840b3fd2d3SAndreas Gohr } 850b3fd2d3SAndreas Gohr 860b3fd2d3SAndreas Gohr /** 870b3fd2d3SAndreas Gohr * @return array 880b3fd2d3SAndreas Gohr */ 89*dad993c5SAndreas Gohr protected function getSocketOptions() : array 900b3fd2d3SAndreas Gohr { 910b3fd2d3SAndreas Gohr $opts = []; 920b3fd2d3SAndreas Gohr 93*dad993c5SAndreas Gohr foreach ($this->socketOpts as $name) { 940b3fd2d3SAndreas Gohr if (isset($this->options[$name])) { 950b3fd2d3SAndreas Gohr $opts[$name] = $this->options[$name]; 960b3fd2d3SAndreas Gohr } 970b3fd2d3SAndreas Gohr } 980b3fd2d3SAndreas Gohr 990b3fd2d3SAndreas Gohr return $opts; 1000b3fd2d3SAndreas Gohr } 1010b3fd2d3SAndreas Gohr} 102