Не удается получить ответ с https серверов используя socket
Моя проблема заключается в подачи запроса на сервера которые имеют ssl, и нужно подавать запросы используя https соединение.
Если я буду испоьзовать curl, тогда я не могу делать одновременно много подключений на сервера, а так как в php много-поточность(thread) вообще не развета, то следовательно мне данный вариант не подходит, как и вариант использовать file_get_contents, так как опять же, мне нужно несколько соединений поддерживать одновренено, а не одно.
Так-же есть stream соединения, и у них достаточно много функций.
В том числе можно используя параметры запроса отключить проверку сертификата соединения, но я не сильно знаком с stream, по этому не хотел его использовать.
Если же говорить о socket, то у него нет возможности установить verify_ssl используя к примеру функцию socket_set_option (по крайне мере я не нашел, по этому и задаю этот вопрос).
По сути если данный вопрос сказать очень кратко:
То во-первых как можно подать запрос на сервера https(ssl)
И во-вторых чтобы была возможность использовать одновременно несколько подключений с серверами.
Сразу же скажу заранее, что я не умею работать с соединениями https.
Пока что разобрался только как работать с web-socket соединениями используя php.
По этому мой вариант реализации может быть не правельный.
Хотя если работать с web-socket и наследовать SocketClient, тогда все нормально работает.
Код мой и его не мало, но надеюсь что он вам будет понятен и логичен. По крайне мере вроде как стандартам он подчиняется.
Файл: SocketThread.php
<?php
final class SocketThread
{
private static $processes = [];
private static $callbacks = [];
private static function runner(Socket $connection): void
{
$conn = array_search($connection, self::$processes);
$func = self::$callbacks[$conn];
$func();
}
private static function logger(Socket $connection): void
{
try
{
self::runner($connection);
}
catch (Exception $error)
{
# error handler
}
}
private static function parser(array $events): void
{
foreach ($events as $connection)
{
self::logger($connection);
}
}
public static function listen(): bool
{
if (count(self::$processes) === 0)
{
return false;
}
$write = null;
$error = null;
$events = self::$processes;
$status = socket_select($events, $write, $error, null);
if ($status !== false)
{
self::parser($events);
}
return true;
}
public static function remove(int $process): void
{
array_splice(self::$processes, $process, 1);
array_splice(self::$callbacks, $process, 1);
}
public static function create(Socket $connection, callable|string|array $callback): int
{
$conn = array_push(self::$processes, $connection);
$func = array_push(self::$callbacks, $callback);
if ($conn === $func)
{
return $conn;
}
throw new Exception();
}
public static function killed(): void
{
foreach (self::$processes as $position => $connection)
{
self::remove($position);
socket_close($connection);
}
}
}
register_shutdown_function([SocketThread::class, 'killed']);
?>
Файл: SocketEvents.php
<?php
class SocketEvents
{
protected function on_message(string $message): void
{
}
protected function on_error(int $code, string $text): void
{
}
protected function on_close(): void
{
}
protected function on_open(): void
{
}
}
?>
Файл: SocketClient.php
<?php
class SocketClient extends SocketEvents
{
private $connect;
private $process;
protected final function write(string $buffer): void
{
socket_write($this->connect, $buffer);
}
protected final function close(): void
{
SocketThread::remove($this->process);
socket_close($this->connect);
$this->on_close();
}
public final function message_handler(): void
{
$buffer = null;
$status = socket_recv($this->connect, $buffer, 1024, 0);
if ($status === false)
{
$code = socket_last_error($this->connect);
$text = socket_strerror($code);
$this->on_error($code, $text);
}
if ($status == false)
{
$this->close();
return;
}
$this->on_message($buffer);
}
public function __construct(Socket $connection)
{
$this->process = SocketThread::create($connection, [$this, 'message_handler']);
$this->connect = $connection;
$this->on_open();
}
}
?>
Файл: SocketSender.php
<?php
class SocketSender extends SocketClient
{
private const PROXY_HOST = '';
private const PROXY_PORT = 0;
private $host;
private $path;
protected function on_open(): void
{
$this->write(implode("\r\n", [
'GET ' . $this->path . ' HTTP/1.1',
'Content-Type: application/json',
'Content-Length: 0',
'Connection: Close',
'Host: ' . $this->host
]));
}
public function __construct(string $host, string $path)
{
$this->host = $host;
$this->path = $path;
$connection = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($connection, self::PROXY_HOST, self::PROXY_PORT);
socket_set_nonblock($connection);
parent::__construct($connection);
}
}
?>
Файл: index.php
<?php
error_reporting(E_ALL);
set_time_limit(0);
require './SocketThread.php';
require './SocketEvents.php';
require './SocketClient.php';
require './SocketSender.php';
(new class extends SocketSender
{
protected function on_message(string $message): void
{
echo $message . PHP_EOL;
}
public function __construct()
{
parent::__construct('google.com', '/');
}
});
while (SocketThread::listen())
{
}
?>