. * * @author Daniil Gentili * @copyright 2016-2020 Daniil Gentili * @license https://opensource.org/licenses/AGPL-3.0 AGPLv3 * * @link https://docs.madelineproto.xyz MadelineProto documentation */ namespace danog\MadelineProto; use Amp\CancellationToken; use Amp\MultiReasonException; use Amp\NullCancellationToken; use Amp\Promise; use Amp\Socket\ConnectContext; use Amp\Socket\Connector; class ContextConnector implements Connector { private $dataCenter; private $logger; private $fromDns = false; public function __construct(DataCenter $dataCenter, bool $fromDns = false) { $this->dataCenter = $dataCenter; $this->fromDns = $fromDns; $this->logger = $dataCenter->getAPI()->getLogger(); } public function connect(string $uri, ?ConnectContext $ctx = null, ?CancellationToken $token = null): Promise { return Tools::call((function () use ($uri, $ctx, $token): \Generator { $ctx = $ctx ?? new ConnectContext(); $token = $token ?? new NullCancellationToken(); $ctxs = $this->dataCenter->generateContexts(0, $uri, $ctx); if (empty($ctxs)) { throw new Exception("No contexts for raw connection to URI {$uri}"); } foreach ($ctxs as $ctx) { /* @var $ctx \danog\MadelineProto\Stream\ConnectionContext */ try { $ctx->setIsDns($this->fromDns); $ctx->setCancellationToken($token); $result = (yield from $ctx->getStream()); $this->logger->logger('OK!', \danog\MadelineProto\Logger::WARNING); return $result->getSocket(); } catch (\Throwable $e) { if (@\constant("MADELINEPROTO_TEST") === 'pony') { throw $e; } $this->logger->logger('Connection failed: '.$e, \danog\MadelineProto\Logger::ERROR); if ($e instanceof MultiReasonException) { foreach ($e->getReasons() as $reason) { $this->logger->logger('Multireason: '.$reason, \danog\MadelineProto\Logger::ERROR); } } } } throw new \danog\MadelineProto\Exception("Could not connect to URI {$uri}"); })()); } }