Асинхронность, потоковая передача открытого текста TCP/IP и безопасные соединения сервера сокетов TLS и клиентские соединения для ReactPHP.
Версия для разработки: эта ветка содержит код для предстоящего выпуска v3. Код текущей стабильной версии v1 можно найти в ветке
1.x
Предстоящий выпуск v3 станет шагом вперед для этого пакета. Тем не менее, мы по-прежнему будем активно поддерживать версию 1 для тех, кто еще не использует последнюю версию. Дополнительную информацию см. также в инструкциях по установке.
Библиотека сокетов предоставляет повторно используемые интерфейсы для сервера и клиента уровня сокетов на основе компонентов EventLoop
и Stream
. Его серверный компонент позволяет создавать сетевые серверы, которые принимают входящие соединения от сетевых клиентов (например, HTTP-сервера). Его клиентский компонент позволяет создавать сетевые клиенты, которые устанавливают исходящие соединения с сетевыми серверами (например, HTTP или клиент базы данных). Эта библиотека предоставляет для всего этого средства асинхронной потоковой передачи, поэтому вы можете обрабатывать несколько одновременных подключений без блокировки.
Оглавление
Вот сервер, который закрывает соединение, если вы что-нибудь отправите:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " Hello " . $ connection -> getRemoteAddress () . " ! n" );
$ connection -> write ( " Welcome to this amazing server! n" );
$ connection -> write ( " Here's a tip: don't say anything. n" );
$ connection -> on ( ' data ' , function ( $ data ) use ( $ connection ) {
$ connection -> close ();
});
});
См. также примеры.
Вот клиент, который выводит выходные данные указанного сервера, а затем пытается отправить ему строку:
$ connector = new React Socket Connector ();
$ connector -> connect ( ' 127.0.0.1:8080 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> pipe ( new React Stream WritableResourceStream ( STDOUT ));
$ connection -> write ( " Hello World! n" );
}, function ( Exception $ e ) {
echo ' Error: ' . $ e -> getMessage () . PHP_EOL ;
});
ConnectionInterface
используется для представления любого входящего и исходящего соединения, например обычного соединения TCP/IP.
Входящее или исходящее соединение — это дуплексный поток (доступный как для чтения, так и для записи), который реализует React DuplexStreamInterface
. Он содержит дополнительные свойства для локального и удаленного адреса (IP-адреса клиента), с которого и с которого было установлено это соединение.
Чаще всего экземпляры, реализующие этот ConnectionInterface
создаются всеми классами, реализующими ServerInterface
, и используются всеми классами, реализующими ConnectorInterface
.
Поскольку ConnectionInterface
реализует базовый DuplexStreamInterface
вы можете использовать любые его события и методы как обычно:
$ connection -> on ( ' data ' , function ( $ chunk ) {
echo $ chunk ;
});
$ connection -> on ( ' end ' , function () {
echo ' ended ' ;
});
$ connection -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage ();
});
$ connection -> on ( ' close ' , function () {
echo ' closed ' ;
});
$ connection -> write ( $ data );
$ connection -> end ( $ data = null );
$ connection -> close ();
// …
Дополнительные сведения см. в DuplexStreamInterface
.
Метод getRemoteAddress(): ?string
возвращает полный удаленный адрес (URI), с которым было установлено это соединение.
$ address = $ connection -> getRemoteAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Если удаленный адрес не может быть определен или неизвестен в данный момент (например, после закрытия соединения), вместо этого он МОЖЕТ вернуть значение NULL
.
В противном случае он вернет полный адрес (URI) в виде строкового значения, например tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
или unix:///path/to/example.sock
. Обратите внимание, что отдельные компоненты URI зависят от приложения и базового транспортного протокола.
Если это соединение на основе TCP/IP и вам нужен только удаленный IP-адрес, вы можете использовать что-то вроде этого:
$ address = $ connection -> getRemoteAddress ();
$ ip = trim ( parse_url ( $ address , PHP_URL_HOST ), ' [] ' );
echo ' Connection with ' . $ ip . PHP_EOL ;
Метод getLocalAddress(): ?string
возвращает полный локальный адрес (URI), с которым было установлено это соединение.
$ address = $ connection -> getLocalAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Если локальный адрес не может быть определен или неизвестен в данный момент (например, после закрытия соединения), вместо этого он МОЖЕТ вернуть значение NULL
.
В противном случае он вернет полный адрес (URI) в виде строкового значения, например tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
или unix:///path/to/example.sock
. Обратите внимание, что отдельные компоненты URI зависят от приложения и базового транспортного протокола.
Этот метод дополняет метод getRemoteAddress()
, поэтому их не следует путать.
Если ваш экземпляр TcpServer
прослушивает несколько интерфейсов (например, используя адрес 0.0.0.0
), вы можете использовать этот метод, чтобы узнать, какой интерфейс фактически принял это соединение (например, общедоступный или локальный интерфейс).
Если ваша система имеет несколько интерфейсов (например, интерфейс WAN и интерфейс LAN), вы можете использовать этот метод, чтобы узнать, какой интерфейс фактически использовался для этого соединения.
ServerInterface
отвечает за предоставление интерфейса для приема входящих потоковых подключений, например обычного соединения TCP/IP.
Большинство компонентов более высокого уровня (таких как HTTP-сервер) принимают экземпляр, реализующий этот интерфейс, для приема входящих потоковых подключений. Обычно это делается посредством внедрения зависимостей, поэтому довольно просто заменить эту реализацию на любую другую реализацию этого интерфейса. Это означает, что вам СЛЕДУЕТ набирать текст для этого интерфейса, а не для конкретной реализации этого интерфейса.
Помимо определения нескольких методов, этот интерфейс также реализует EventEmitterInterface
, который позволяет вам реагировать на определенные события.
Событие connection
будет генерироваться всякий раз, когда будет установлено новое соединение, т. е. новый клиент подключается к этому сокету сервера:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' new connection ' . PHP_EOL ;
});
См. также ConnectionInterface
для получения более подробной информации об обработке входящего соединения.
Событие error
будет генерироваться всякий раз, когда возникает ошибка при принятии нового соединения от клиента.
$ socket -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage () . PHP_EOL ;
});
Обратите внимание, что это не фатальная ошибка, т. е. сервер продолжает прослушивать новые соединения даже после этого события.
Метод getAddress(): ?string
можно использовать для возврата полного адреса (URI), который в данный момент прослушивает этот сервер.
$ address = $ socket -> getAddress ();
echo ' Server listening on ' . $ address . PHP_EOL ;
Если адрес не может быть определен или неизвестен в данный момент (например, после закрытия сокета), вместо этого он МОЖЕТ вернуть значение NULL
.
В противном случае он вернет полный адрес (URI) в виде строкового значения, например tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
unix://example.sock
или unix:///path/to/example.sock
. Обратите внимание, что отдельные компоненты URI зависят от приложения и базового транспортного протокола.
Если это сервер на базе TCP/IP и вам нужен только локальный порт, вы можете использовать что-то вроде этого:
$ address = $ socket -> getAddress ();
$ port = parse_url ( $ address , PHP_URL_PORT );
echo ' Server listening on port ' . $ port . PHP_EOL ;
Метод pause(): void
можно использовать для приостановки приема новых входящих соединений.
Удаляет ресурс сокета из EventLoop и, таким образом, прекращает принимать новые соединения. Обратите внимание, что сокет прослушивания остается активным и не закрывается.
Это означает, что новые входящие соединения будут оставаться ожидающими в журнале операций операционной системы до тех пор, пока его настраиваемый журнал невыполненных задач не будет заполнен. После заполнения невыполненной очереди операционная система может отклонять дальнейшие входящие соединения до тех пор, пока неиспользованная очередь не будет снова опустошена, возобновив прием новых соединений.
После приостановки работы сервера никакие дальнейшие события connection
НЕ ДОЛЖНЫ генерироваться.
$ socket -> pause ();
$ socket -> on ( ' connection ' , assertShouldNeverCalled ());
Этот метод носит рекомендательный характер, хотя обычно не рекомендуется, поскольку сервер МОЖЕТ продолжать генерировать события connection
.
Если не указано иное, успешно открытый сервер НЕ ДОЛЖЕН запускаться в состоянии паузы.
Вы можете продолжить обработку событий, снова вызвав resume()
.
Обратите внимание, что оба метода могут вызываться любое количество раз, в частности, вызов pause()
более одного раза НЕ ДОЛЖЕН иметь никакого эффекта. Аналогично, вызов этого метода после close()
является НЕОПАСНЫМ.
Метод resume(): void
можно использовать для возобновления приема новых входящих соединений.
Повторно подключите ресурс сокета к EventLoop после предыдущей pause()
.
$ socket -> pause ();
Loop:: addTimer ( 1.0 , function () use ( $ socket ) {
$ socket -> resume ();
});
Обратите внимание, что оба метода можно вызывать любое количество раз, в частности, вызов resume()
без предварительной pause()
НЕ ДОЛЖЕН иметь никакого эффекта. Аналогично, вызов этого метода после close()
является НЕОПАСНЫМ.
Метод close(): void
можно использовать для отключения этого прослушивающего сокета.
Это прекратит прослушивание новых входящих соединений на этом сокете.
echo ' Shutting down server socket ' . PHP_EOL ;
$ socket -> close ();
Вызов этого метода более одного раза в одном и том же экземпляре является NO-OP.
Класс SocketServer
— это основной класс в этом пакете, который реализует ServerInterface
и позволяет принимать входящие потоковые соединения, такие как потоки TCP/IP в виде открытого текста или защищенные потоки соединений TLS.
Чтобы принимать TCP/IP-соединения в открытом виде, вы можете просто передать комбинацию хоста и порта следующим образом:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
Прослушивание адреса локального хоста 127.0.0.1
означает, что он будет недоступен из-за пределов этой системы. Чтобы изменить хост, который прослушивает сокет, вы можете указать IP-адрес интерфейса или использовать специальный адрес 0.0.0.0
для прослушивания на всех интерфейсах:
$ socket = new React Socket SocketServer ( ' 0.0.0.0:8080 ' );
Если вы хотите прослушивать IPv6-адрес, вы ДОЛЖНЫ заключить хост в квадратные скобки:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' );
Чтобы использовать случайное назначение порта, вы можете использовать порт 0
:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:0 ' );
$ address = $ socket -> getAddress ();
Чтобы прослушивать путь сокета домена Unix (UDS), вы ДОЛЖНЫ префикс URI со схемой unix://
:
$ socket = new React Socket SocketServer ( ' unix:///tmp/server.sock ' );
Чтобы прослушивать существующий номер файлового дескриптора (FD), вы ДОЛЖНЫ добавить к URI префикс php://fd/
следующим образом:
$ socket = new React Socket SocketServer ( ' php://fd/3 ' );
Если данный URI недействителен, не содержит порта, какой-либо другой схемы или содержит имя хоста, будет выдано InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ socket = new React Socket SocketServer ( ' 127.0.0.1 ' );
Если данный URI кажется действительным, но его прослушивание не удалось (например, если порт уже используется или порт ниже 1024 может потребовать root-доступа и т. д.), он выдаст исключение RuntimeException
:
$ first = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
// throws RuntimeException because port is already in use
$ second = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
Обратите внимание, что эти состояния ошибок могут различаться в зависимости от вашей системы и/или конфигурации. Дополнительные сведения о фактическом состоянии ошибки см. в сообщении об исключении и коде.
При желании вы можете указать параметры контекста сокета TCP для базового ресурса сокета потока следующим образом:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' , [
' tcp ' => [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]
]);
Обратите внимание, что доступные параметры контекста сокета, их значения по умолчанию и последствия их изменения могут различаться в зависимости от вашей системы и/или версии PHP. Передача неизвестных параметров контекста не имеет никакого эффекта. Параметр контекста
backlog
по умолчанию имеет значение511
, если не указано явно.
Вы можете запустить защищенный сервер TLS (ранее известный как SSL), просто добавив схему URI tls://
. Внутри он будет ожидать соединений TCP/IP в виде открытого текста, а затем выполняет подтверждение TLS для каждого соединения. Таким образом, для этого требуются действительные параметры контекста TLS, которые в своей основной форме могут выглядеть примерно так, если вы используете файл сертификата в кодировке PEM:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8080 ' , [
' tls ' => [
' local_cert ' => ' server.pem '
]
]);
Обратите внимание, что файл сертификата будет загружен не при создании экземпляра, а тогда, когда входящее соединение инициализирует свой контекст TLS. Это означает, что любые неверные пути к файлам сертификатов или их содержимое вызовут событие
error
только в более позднее время.
Если ваш закрытый ключ зашифрован парольной фразой, вам необходимо указать его следующим образом:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]
]);
По умолчанию этот сервер поддерживает TLSv1.0+ и исключает поддержку устаревших SSLv2/SSLv3. Вы также можете явно выбрать версию TLS, которую хотите согласовать с удаленной стороной:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]
]);
Обратите внимание, что доступные параметры контекста TLS, их значения по умолчанию и последствия их изменения могут различаться в зависимости от вашей системы и/или версии PHP. Массив внешнего контекста позволяет одновременно использовать параметры контекста
tcp
(и, возможно, другие). Передача неизвестных параметров контекста не имеет никакого эффекта. Если вы не используете схемуtls://
, передача параметров контекстаtls
не имеет никакого эффекта.
Всякий раз, когда клиент подключается, он генерирует событие connection
с экземпляром соединения, реализующим ConnectionInterface
:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
См. также ServerInterface
для получения более подробной информации.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
Обратите внимание, что класс
SocketServer
представляет собой конкретную реализацию сокетов TCP/IP. Если вы хотите ввести подсказку в реализации протокола более высокого уровня, вам СЛЕДУЕТ использовать вместо этого общийServerInterface
.
Класс TcpServer
реализует ServerInterface
и отвечает за принятие текстовых TCP/IP-соединений.
$ server = new React Socket TcpServer ( 8080 );
Как указано выше, параметр $uri
может состоять только из порта, и в этом случае сервер по умолчанию будет прослушивать адрес локального хоста 127.0.0.1
, что означает, что он будет недоступен из-за пределов этой системы.
Чтобы использовать случайное назначение порта, вы можете использовать порт 0
:
$ server = new React Socket TcpServer ( 0 );
$ address = $ server -> getAddress ();
Чтобы изменить хост, который прослушивает сокет, вы можете указать IP-адрес через первый параметр, предоставленный конструктору, которому может предшествовать схема tcp://
:
$ server = new React Socket TcpServer ( ' 192.168.0.1:8080 ' );
Если вы хотите прослушивать IPv6-адрес, вы ДОЛЖНЫ заключить хост в квадратные скобки:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' );
Если данный URI недействителен, не содержит порта, какой-либо другой схемы или содержит имя хоста, будет выдано InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ server = new React Socket TcpServer ( ' 127.0.0.1 ' );
Если данный URI кажется действительным, но его прослушивание не удалось (например, если порт уже используется или порт ниже 1024 может потребовать root-доступа и т. д.), он выдаст исключение RuntimeException
:
$ first = new React Socket TcpServer ( 8080 );
// throws RuntimeException because port is already in use
$ second = new React Socket TcpServer ( 8080 );
Обратите внимание, что эти состояния ошибок могут различаться в зависимости от вашей системы и/или конфигурации. Дополнительные сведения о фактическом состоянии ошибки см. в сообщении об исключении и коде.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
При желании вы можете указать параметры контекста сокета для базового ресурса сокета потока следующим образом:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' , null , [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]);
Обратите внимание, что доступные параметры контекста сокета, их значения по умолчанию и последствия их изменения могут различаться в зависимости от вашей системы и/или версии PHP. Передача неизвестных параметров контекста не имеет никакого эффекта. Параметр контекста
backlog
по умолчанию имеет значение511
, если не указано явно.
Всякий раз, когда клиент подключается, он генерирует событие connection
с экземпляром соединения, реализующим ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
См. также ServerInterface
для получения более подробной информации.
Класс SecureServer
реализует ServerInterface
и отвечает за обеспечение безопасного сервера TLS (ранее известного как SSL).
Это делается путем создания оболочки экземпляра TcpServer
, который ожидает соединений TCP/IP в виде открытого текста, а затем выполняет подтверждение TLS для каждого соединения. Таким образом, для этого требуются действительные параметры контекста TLS, которые в своей основной форме могут выглядеть примерно так, если вы используете файл сертификата в кодировке PEM:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem '
]);
Обратите внимание, что файл сертификата будет загружен не при создании экземпляра, а тогда, когда входящее соединение инициализирует свой контекст TLS. Это означает, что любые неверные пути к файлам сертификатов или их содержимое вызовут
error
только в более позднее время.
Если ваш закрытый ключ зашифрован парольной фразой, вам необходимо указать его следующим образом:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]);
По умолчанию этот сервер поддерживает TLSv1.0+ и исключает поддержку устаревших SSLv2/SSLv3. Вы также можете явно выбрать версию TLS, которую хотите согласовать с удаленной стороной:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]);
Обратите внимание, что доступные параметры контекста TLS, их значения по умолчанию и последствия их изменения могут различаться в зависимости от вашей системы и/или версии PHP. Передача неизвестных параметров контекста не имеет никакого эффекта.
Всякий раз, когда клиент завершает рукопожатие TLS, он генерирует событие connection
с экземпляром соединения, реализующим ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Secure connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Всякий раз, когда клиенту не удается выполнить успешное подтверждение TLS, он выдает событие error
, а затем закрывает базовое соединение TCP/IP:
$ server -> on ( ' error ' , function ( Exception $ e ) {
echo ' Error ' . $ e -> getMessage () . PHP_EOL ;
});
См. также ServerInterface
для получения более подробной информации.
Обратите внимание, что класс SecureServer
представляет собой конкретную реализацию сокетов TLS. Если вы хотите ввести подсказку в реализации протокола более высокого уровня, вам СЛЕДУЕТ использовать вместо этого общий ServerInterface
.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
Расширенное использование: несмотря на то, что любой
ServerInterface
разрешен в качестве первого параметра, вам СЛЕДУЕТ передать экземплярTcpServer
в качестве первого параметра, если вы не знаете, что делаете. ВнутриSecureServer
должен установить необходимые параметры контекста TLS для базовых ресурсов потока. Эти ресурсы не предоставляются ни через один из интерфейсов, определенных в этом пакете, а только через внутренний классConnection
. КлассTcpServer
гарантированно создает соединения, реализующиеConnectionInterface
, и использует внутренний классConnection
для предоставления этих базовых ресурсов. Если вы используете пользовательскийServerInterface
и его событиеconnection
не соответствует этому требованию,SecureServer
выдаст событиеerror
, а затем закроет базовое соединение.
Класс UnixServer
реализует ServerInterface
и отвечает за прием соединений через сокеты домена Unix (UDS).
$ server = new React Socket UnixServer ( ' /tmp/server.sock ' );
Как и выше, параметр $uri
может состоять только из пути к сокету или пути к сокету с префиксом схемы unix://
.
Если данный URI кажется действительным, но его прослушивание не удалось (например, если сокет уже используется или файл недоступен и т. д.), он выдаст RuntimeException
:
$ first = new React Socket UnixServer ( ' /tmp/same.sock ' );
// throws RuntimeException because socket is already in use
$ second = new React Socket UnixServer ( ' /tmp/same.sock ' );
Обратите внимание, что эти состояния ошибок могут различаться в зависимости от вашей системы и/или конфигурации. В частности, Zend PHP сообщает о «Неизвестной ошибке» только в том случае, если путь UDS уже существует и не может быть привязан. Возможно, вы захотите проверить
is_file()
по заданному пути UDS, чтобы в этом случае получить более удобное для пользователя сообщение об ошибке. Дополнительные сведения о фактическом состоянии ошибки см. в сообщении об исключении и коде.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
Всякий раз, когда клиент подключается, он генерирует событие connection
с экземпляром соединения, реализующим ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' New connection ' . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
См. также ServerInterface
для получения более подробной информации.
Декоратор LimitingServer
оборачивает данный ServerInterface
и отвечает за ограничение и отслеживание открытых подключений к этому экземпляру сервера.
Всякий раз, когда базовый сервер генерирует событие connection
, он проверяет свои ограничения, а затем либо
connection
error
.Всякий раз, когда соединение закрывается, оно удаляется из списка открытых соединений.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
См. также второй пример для более подробной информации.
Вам необходимо передать максимальное количество открытых соединений, чтобы сервер автоматически отклонял (закрывал) соединения при превышении этого предела. В этом случае он выдаст событие error
, информирующее об этом, и событие connection
не будет генерироваться.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Вы МОЖЕТЕ передать null
предел, чтобы не налагать ограничений на количество открытых соединений и продолжать принимать новые соединения до тех пор, пока у вас не закончатся ресурсы операционной системы (например, дескрипторы открытых файлов). Это может быть полезно, если вы не хотите заботиться о применении ограничения, но все же хотите использовать метод getConnections()
.
При желании вы можете настроить сервер на приостановку приема новых подключений после достижения лимита подключений. В этом случае он приостанавливает базовый сервер и больше не обрабатывает новые соединения вообще, а значит, и не закрывает лишние соединения. Базовая операционная система отвечает за сохранение очереди ожидающих подключений до тех пор, пока не будет достигнут ее предел, после чего она начнет отклонять дальнейшие подключения. Как только сервер достигнет предела количества подключений, он продолжит использовать соединения из невыполненной работы и будет обрабатывать любые ожидающие данные для каждого соединения. Этот режим может быть полезен для некоторых протоколов, предназначенных для ожидания ответного сообщения (например, HTTP), но может быть менее полезен для других протоколов, требующих немедленных ответов (например, приветственного сообщения в интерактивном чате).
$ server = new React Socket LimitingServer ( $ server , 100 , true );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Метод getConnections(): ConnectionInterface[]
можно использовать для возврата массива со всеми активными в данный момент соединениями.
foreach ( $ server -> getConnection () as $ connection ) {
$ connection -> write ( ' Hi! ' );
}
ConnectorInterface
отвечает за предоставление интерфейса для установления потоковых соединений, например обычного соединения TCP/IP.
Это основной интерфейс, определенный в этом пакете, и он используется во всей обширной экосистеме React.
Большинство компонентов более высокого уровня (таких как HTTP, базы данных или клиенты других сетевых служб) принимают экземпляр, реализующий этот интерфейс, для создания TCP/IP-соединения с базовой сетевой службой. Обычно это делается посредством внедрения зависимостей, поэтому довольно просто заменить эту реализацию на любую другую реализацию этого интерфейса.
Интерфейс предлагает только один метод:
Метод connect(string $uri): PromiseInterface<ConnectionInterface>
можно использовать для создания потокового подключения к заданному удаленному адресу.
Он возвращает обещание, которое либо выполняется с потоком, реализующим ConnectionInterface
в случае успеха, либо отклоняется с Exception
если соединение не удалось:
$ connector -> connect ( ' google.com:443 ' )-> then (
function ( React Socket ConnectionInterface $ connection ) {
// connection successfully established
},
function ( Exception $ error ) {
// failed to connect due to $error
}
);
См. также ConnectionInterface
для получения более подробной информации.
Возвращенное обещание ДОЛЖНО быть реализовано таким образом, чтобы его можно было отменить, пока оно еще находится в состоянии ожидания. Отмена ожидающего обещания ДОЛЖНА отвергнуть его значение с помощью Exception
. Ему СЛЕДУЕТ очистить все базовые ресурсы и ссылки, если это применимо:
$ promise = $ connector -> connect ( $ uri );
$ promise -> cancel ();
Класс Connector
— это основной класс в этом пакете, который реализует ConnectorInterface
и позволяет создавать потоковые соединения.
Этот соединитель можно использовать для создания потоков потоковой передачи любого типа, например текстового TCP/IP, безопасного TLS или локальных потоков подключений Unix.
Он привязывается к основному циклу событий и может использоваться следующим образом:
$ connector = new React Socket Connector ();
$ connector -> connect ( $ uri )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
}, function ( Exception $ e ) {
echo ' Error: ' . $ e -> getMessage () . PHP_EOL ;
});
Чтобы создать TCP/IP-соединение в виде открытого текста, вы можете просто передать комбинацию хоста и порта следующим образом:
$ connector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Если вы не укажете схему URI в URI назначения, он примет
tcp://
по умолчанию и установит соединение TCP/IP в виде открытого текста. Обратите внимание, что для соединений TCP/IP требуется часть хоста и порта в URI назначения, как указано выше, все остальные компоненты URI являются необязательными.
Чтобы создать безопасное соединение TLS, вы можете использовать схему URI tls://
следующим образом:
$ connector -> connect ( ' tls://www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Чтобы создать подключение к локальному сокету домена Unix, вы можете использовать схему URI unix://
следующим образом:
$ connector -> connect ( ' unix:///tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Метод
getRemoteAddress()
вернет путь к целевому доменному сокету Unix (UDS), заданный методуconnect()
, включая схемуunix://
, напримерunix:///tmp/demo.sock
. МетодgetLocalAddress()
скорее всего, вернетnull
значение, поскольку здесь это значение неприменимо к соединениям UDS.
Под капотом Connector
реализован как фасад более высокого уровня для соединителей нижнего уровня, реализованных в этом пакете. Это означает, что он также разделяет все их функции и детали реализации. Если вы хотите вводить подсказки в реализации протокола более высокого уровня, вам СЛЕДУЕТ использовать вместо этого общий ConnectorInterface
.
Начиная с v1.4.0
, класс Connector
по умолчанию использует алгоритм счастливых глаз для автоматического подключения через IPv4 или IPv6 при указании имени хоста. При этом автоматически предпринимается попытка подключения с использованием как IPv4, так и IPv6 одновременно (предпочтительно IPv6), что позволяет избежать обычных проблем, с которыми сталкиваются пользователи с несовершенными соединениями или настройками IPv6. Если вы хотите вернуться к старому поведению, когда выполнялся только поиск IPv4 и пытались установить только одно соединение IPv4, вы можете настроить Connector
следующим образом:
$ connector = new React Socket Connector ([
' happy_eyeballs ' => false
]);
Аналогичным образом вы также можете повлиять на поведение DNS по умолчанию следующим образом. Класс Connector
попытается определить настройки DNS вашей системы (и использует общедоступный DNS-сервер Google 8.8.8.8
в качестве запасного варианта, если не удается определить настройки вашей системы), чтобы по умолчанию преобразовать все общедоступные имена хостов в базовые IP-адреса. Если вы явно хотите использовать собственный DNS-сервер (например, локальный ретранслятор DNS или DNS-сервер всей компании), вы можете настроить Connector
следующим образом:
$ connector = new React Socket Connector ([
' dns ' => ' 127.0.1.1 '
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Если вы вообще не хотите использовать преобразователь DNS и хотите подключаться только к IP-адресам, вы также можете настроить свой Connector
следующим образом:
$ connector = new React Socket Connector ([
' dns ' => false
]);
$ connector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Дополнительно: если вам нужен собственный экземпляр DNS ReactDnsResolverResolverInterface
, вы также можете настроить свой Connector
следующим образом:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ resolver = $ dnsResolverFactory -> createCached ( ' 127.0.1.1 ' );
$ connector = new React Socket Connector ([
' dns ' => $ resolver
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
По умолчанию схемы URI tcp://
и tls://
будут использовать значение таймаута, соответствующее вашему ini-настройке default_socket_timeout
(которое по умолчанию равно 60 с). Если вам нужно собственное значение тайм-аута, вы можете просто передать его следующим образом:
$ connector = new React Socket Connector ([
' timeout ' => 10.0
]);
Аналогично, если вы вообще не хотите применять тайм-аут и позволить операционной системе справиться с этим, вы можете передать логический флаг следующим образом:
$ connector = new React Socket Connector ([
' timeout ' => false
]);
По умолчанию Connector
поддерживает схемы URI tcp://
, tls://
и unix://
. Если вы хотите явно запретить что-либо из этого, вы можете просто передать логические флаги следующим образом:
// only allow secure TLS connections
$ connector = new React Socket Connector ([
' tcp ' => false ,
' tls ' => true ,
' unix ' => false ,
));
$ connector -> connect ( ' tls://google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
tcp://
и tls://
также принимают дополнительные параметры контекста, передаваемые базовым соединителям. Если вы хотите явно передать дополнительные параметры контекста, вы можете просто передать массивы параметров контекста следующим образом:
// allow insecure TLS connections
$ connector = new React Socket Connector ([
' tcp ' => [
' bindto ' => ' 192.168.0.1:0 '
],
' tls ' => [
' verify_peer ' => false ,
' verify_peer_name ' => false
],
]);
$ connector -> connect ( ' tls://localhost:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
По умолчанию этот соединитель поддерживает TLSv1.0+ и исключает поддержку устаревших SSLv2/SSLv3. Вы также можете явно выбрать версию TLS, которую хотите согласовать с удаленной стороной:
$ connector = new React Socket Connector ([
' tls ' => [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]
]);
Для получения более подробной информации о параметрах контекста обратитесь к документации PHP, посвященной параметрам контекста сокета и параметрам контекста SSL.
Дополнительно: по умолчанию Connector
поддерживает схемы URI tcp://
, tls://
и unix://
. Для этого он автоматически настраивает необходимые классы соединителей. Если вы хотите явно передать пользовательские соединители для любого из них, вы можете просто передать экземпляр, реализующий ConnectorInterface
следующим образом:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ resolver = $ dnsResolverFactory -> createCached ( ' 127.0.1.1 ' );
$ tcp = new React Socket HappyEyeBallsConnector ( null , new React Socket TcpConnector (), $ resolver );
$ tls = new React Socket SecureConnector ( $ tcp );
$ unix = new React Socket UnixConnector ();
$ connector = new React Socket Connector ([
' tcp ' => $ tcp ,
' tls ' => $ tls ,
' unix ' => $ unix ,
' dns ' => false ,
' timeout ' => false ,
]);
$ connector -> connect ( ' google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Внутренне соединитель
tcp://
всегда будет заключен в DNS-преобразователь, если вы не отключите DNS, как в приведенном выше примере. В этом случае соединительtcp://
получает фактическое имя хоста, а не только разрешенный IP-адрес, и, таким образом, отвечает за выполнение поиска. Внутри автоматически создаваемый соединительtls://
всегда будет оборачивать базовый соединительtcp://
для установления базового соединения TCP/IP в виде открытого текста перед включением безопасного режима TLS. Если вы хотите использовать собственный базовый соединительtcp://
только для безопасных соединений TLS, вместо этого вы можете явно передать соединительtls://
, как указано выше. Внутренне соединителиtcp://
иtls://
всегда будут обернутыTimeoutConnector
, если вы не отключите таймауты, как в приведенном выше примере.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
Класс TcpConnector
реализует ConnectorInterface
и позволяет создавать TCP/IP-соединения в виде открытого текста с любой комбинацией IP-портов:
$ tcpConnector = new React Socket TcpConnector ();
$ tcpConnector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
См. также примеры.
Ожидающие попытки подключения можно отменить, отменив ожидающее обещание следующим образом:
$ promise = $ tcpConnector -> connect ( ' 127.0.0.1:80 ' );
$ promise -> cancel ();
Вызов cancel()
для ожидающего обещания закроет базовый ресурс сокета, тем самым отменяя ожидающее соединение TCP/IP и отклоняя полученное обещание.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
При желании вы можете передать конструктору дополнительные параметры контекста сокета следующим образом:
$ tcpConnector = new React Socket TcpConnector ( null , [
' bindto ' => ' 192.168.0.1:0 '
]);
Обратите внимание, что этот класс позволяет подключаться только к комбинациям IP-портов. Если данный URI недействителен, не содержит допустимого IP-адреса и порта или содержит какую-либо другую схему, он будет отклонен с исключением InvalidArgumentException
:
Если данный URI кажется действительным, но подключиться к нему не удается (например, если удаленный хост отклоняет соединение и т. д.), он будет отклонен с RuntimeException
.
Если вы хотите подключиться к комбинациям имени хоста-порта, см. также следующую главу.
Расширенное использование: внутри
TcpConnector
выделяет пустой ресурс контекста для каждого ресурса потока. Если URI назначения содержит параметр запросаhostname
, его значение будет использоваться для настройки имени однорангового узла TLS. Оно используетсяSecureConnector
иDnsConnector
для проверки имени однорангового узла, а также может использоваться, если вам нужно собственное имя однорангового узла TLS.
Класс HappyEyeBallsConnector
реализует ConnectorInterface
и позволяет создавать TCP/IP-соединения в виде открытого текста с любой комбинацией имени хоста-порта. Внутри он реализует алгоритм счастливых глаз из RFC6555
и RFC8305
для поддержки имен хостов IPv6 и IPv4.
Это достигается путем оформления данного экземпляра TcpConnector
таким образом, чтобы он сначала искал заданное имя домена через DNS (если применимо), а затем устанавливал базовое TCP/IP-соединение с разрешенным целевым IP-адресом.
Обязательно настройте преобразователь DNS и базовый коннектор TCP следующим образом:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ dns = $ dnsResolverFactory -> createCached ( ' 8.8.8.8 ' );
$ dnsConnector = new React Socket HappyEyeBallsConnector ( null , $ tcpConnector , $ dns );
$ dnsConnector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
См. также примеры.
Ожидающие попытки подключения можно отменить, отменив ожидающее обещание следующим образом:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Вызов cancel()
для ожидающего обещания отменит базовые запросы DNS и/или базовые соединения TCP/IP и отклонит полученное обещание.
Этот класс принимает необязательный параметр LoopInterface|null $loop
, который можно использовать для передачи экземпляра цикла событий, который будет использоваться для этого объекта. Здесь вы можете использовать null
значение, чтобы использовать цикл по умолчанию. Это значение НЕ СЛЕДУЕТ задавать, если вы не уверены, что хотите явно использовать данный экземпляр цикла событий.
Расширенное использование: внутри
HappyEyeBallsConnector
используетсяResolver
для поиска IP-адресов для данного имени хоста. Затем он заменит имя хоста в URI назначения на этот IP-адрес, добавит параметр запросаhostname
и передаст этот обновленный URI базовому соединителю. Алгоритм Happy Eye Balls описывает поиск адреса IPv6 и IPv4 для заданного имени хоста, поэтому этот соединитель отправляет два запроса DNS для записей A и AAAA. Затем он использует все IP-адреса (как v6, так и v4) и пытается подключиться ко всем из них с интервалом 50 мс между ними. Переключение адресов IPv6 и IPv4. Когда соединение установлено, все остальные запросы DNS и попытки подключения отменяются.
Класс DnsConnector
реализует ConnectorInterface
и позволяет создавать TCP/IP-соединения в виде открытого текста с любой комбинацией имени хоста-порта.
Это достигается путем оформления данного экземпляра TcpConnector
таким образом, чтобы он сначала искал заданное имя домена через DNS (если применимо), а затем устанавливал базовое TCP/IP-соединение с разрешенным целевым IP-адресом.
Обязательно настройте преобразователь DNS и базовый коннектор TCP следующим образом:
$ dnsResolverFactory = new React Dns Resolver Factory ();
$ dns = $ dnsResolverFactory -> createCached ( ' 8.8.8.8 ' );
$ dnsConnector = new React Socket DnsConnector ( $ tcpConnector , $ dns );
$ dnsConnector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
См. также примеры.
Ожидающие попытки подключения можно отменить, отменив ожидающее обещание следующим образом:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Вызов cancel()
для ожидающего обещания отменит базовый поиск DNS и/или базовое соединение TCP/IP и отклонит полученное обещание.
Расширенное использование: Внутренне
DnsConnector
используетReactDnsResolverResolverInterface
для поиска IP-адреса для данного имени хоста. Затем он заменит имя хоста в URI назначения на этот IP-адрес, добавит параметр запросаhostname
и передаст этот обновленный URI базовому соединителю. Таким образом, базовый соединитель отвечает за создание соединения с целевым IP-адресом, в то время как этот параметр запроса может использоваться для проверки исходного имени хоста и используетсяTcpConnector
для настройки имени однорангового узла TLS. Еслиhostname
указано явно, этот параметр запроса не будет изменен, что может быть полезно, если вам нужно собственное имя однорангового узла TLS.
Класс SecureConnector
реализует ConnectorInterface
и позволяет создавать безопасные соединения TLS (ранее известные как SSL) к любой комбинации имени хоста-порта.
Это достигается путем украшения данного экземпляра DnsConnector
так, чтобы он сначала создавал TCP/IP-соединение в виде открытого текста, а затем включал шифрование TLS в этом потоке.
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector );
$ secureConnector -> connect ( ' www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " GET / HTTP/1.0 rn Host: www.google.com rnrn" );
. . .
});
См. также примеры.
Ожидающие попытки подключения могут быть отменены путем отмены ожидающего обещания так:
$ promise = $ secureConnector -> connect ( ' www.google.com:443 ' );
$ promise -> cancel ();
Вызовов cancel()
в ожидаемом обещании отменит базовое соединение TCP/IP и/или переговоры SSL/TLS и отклонит результирующее обещание.
Этот класс принимает дополнительный параметр LoopInterface|null $loop
, который можно использовать для прохождения экземпляра цикла событий для использования для этого объекта. Вы можете использовать null
значение здесь, чтобы использовать цикл по умолчанию. Это значение не должно быть дано, если вы не уверены, что хотите явно использовать экземпляр цикла данного события.
Вы можете при желании передать дополнительные параметры контекста SSL в конструктор, как это:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' verify_peer ' => false ,
' verify_peer_name ' => false
]);
По умолчанию этот разъем поддерживает TLSV1.0+ и исключает поддержку Legacy SSLV2/SSLV3. Вы также можете явно выбрать версию TLS, которую вы хотите договориться с удаленной стороной:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]);
Расширенное использование: Внутренне,
SecureConnector
полагается на настройку необходимых параметров контекста в базовом потоке ресурса. Таким образом, он должен использоваться сTcpConnector
где -то в стеке соединительных соединений, чтобы он мог выделять пустой контекстный ресурс для каждого ресурса потока и проверить имя сверстника. Неспособность сделать это может привести к ошибке несоответствия именных имен TLS или какой -то трудности для отслеживания расовых условий, потому что все ресурсы потока будут использовать один общий контекстный ресурс по умолчанию в противном случае.
Класс TimeoutConnector
реализует ConnectorInterface
и позволяет добавлять обработку тайм -аута в любой существующий экземпляр соединителя.
Это происходит путем украшения любого данного экземпляра ConnectorInterface
и запуска таймера, который автоматически отклонит и прерван любую базовую попытку подключения, если это займет слишком много времени.
$ timeoutConnector = new React Socket TimeoutConnector ( $ connector , 3.0 );
$ timeoutConnector -> connect ( ' google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
// connection succeeded within 3.0 seconds
});
Смотрите также любой из примеров.
Этот класс принимает дополнительный параметр LoopInterface|null $loop
, который можно использовать для прохождения экземпляра цикла событий для использования для этого объекта. Вы можете использовать null
значение здесь, чтобы использовать цикл по умолчанию. Это значение не должно быть дано, если вы не уверены, что хотите явно использовать экземпляр цикла данного события.
Ожидающие попытки подключения могут быть отменены путем отмены ожидающего обещания так:
$ promise = $ timeoutConnector -> connect ( ' google.com:80 ' );
$ promise -> cancel ();
Призыв cancel()
в ожидаемом обещании отменит попытку подключения, прерванте таймер и отклонит результирующее обещание.
Класс UnixConnector
реализует ConnectorInterface
и позволяет подключаться к путям Unix Domain Gropt (UDS), как это:
$ connector = new React Socket UnixConnector ();
$ connector -> connect ( ' /tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " HELLO n" );
});
Подключение к гнездам Unix домена - это атомная операция, то есть его обещание будет сразу урегулировать (либо разрешить, либо отвергнуть). Таким образом, призыв cancel()
в результате обещания не влияет.
Метод
getRemoteAddress()
будет возвращать целевой путь доменного сокета Unix (UDS), как указано в методеconnect()
, приготовленной с помощью схемыunix://
, напримерunix:///tmp/demo.sock
. МетодgetLocalAddress()
скорее всего, вернетnull
значение, поскольку это значение не применимо к соединениям UDS здесь.
Этот класс принимает дополнительный параметр LoopInterface|null $loop
, который можно использовать для прохождения экземпляра цикла событий для использования для этого объекта. Вы можете использовать null
значение здесь, чтобы использовать цикл по умолчанию. Это значение не должно быть дано, если вы не уверены, что хотите явно использовать экземпляр цикла данного события.
Класс FixedUriConnector
реализует ConnectorInterface
и украшает существующий разъем, чтобы всегда использовать фиксированный, предварительно сконфигурированный URI.
Это может быть полезно для потребителей, которые не поддерживают определенные URI, например, когда вы хотите явно подключиться к пути Unix Domain Goot (UDS) вместо подключения к адресу по умолчанию, предполагаемому API более высокого уровня:
$ connector = new React Socket FixedUriConnector (
' unix:///var/run/docker.sock ' ,
new React Socket UnixConnector ()
);
// destination will be ignored, actually connects to Unix domain socket
$ promise = $ connector -> connect ( ' localhost:80 ' );
Рекомендуемый способ установки этой библиотеки — через Composer. Впервые в Composer?
После выпуска этот проект будет следовать за SemVer. На данный момент будет установлена последняя разрабатываемая версия:
composer require react/socket:^3@dev
См. также CHANGELOG для получения подробной информации об обновлениях версий.
Этот проект предназначен для работы на любой платформе и, следовательно, не требует каких-либо расширений PHP и поддерживает работу с PHP 7.1 до текущей версии PHP 8+. Для этого проекта настоятельно рекомендуется использовать последнюю поддерживаемую версию PHP .
Legacy PHP <7.3.3 (и PHP <7.2.15) страдает от ошибки, в которой FeOF () может блокировать 100% использование ЦП на фрагментированных записях TLS. Мы стараемся обойти это, всегда потребляя полный буфер приема одновременно, чтобы избежать устаревших данных в буферах TLS. Известно, что это работает вокруг высокого использования ЦП для благополучия сверстников, но это может привести к очень большим кускам данных для сценариев высокой пропускной способности. Поведение багги по -прежнему может быть вызвано из -за сетевых буферов ввода -вывода или злонамеренных коллег на пораженных версиях, настоятельно рекомендуется.
Legacy PHP <7.1.4 страдает от ошибки при написании больших кусков данных по потокам TLS одновременно. Мы стараемся обойти это, ограничивая размер записи чанка до 8192 байтов только для старых версий PHP. Это всего лишь обходная работа и имеет заметный штраф за эффективность на пострадавших версиях.
Чтобы запустить набор тестов, вам сначала необходимо клонировать этот репозиторий, а затем установить все зависимости через Composer:
composer install
Чтобы запустить набор тестов, перейдите в корень проекта и запустите:
vendor/bin/phpunit
Тестовый набор также содержит ряд тестов функциональной интеграции, которые полагаются на стабильное интернет -соединение. Если вы не хотите запускать их, их можно просто пропустить так:
vendor/bin/phpunit --exclude-group internet
MIT, см. файл ЛИЦЕНЗИИ.