Asíncrono, transmisión de texto sin formato TCP/IP y conexiones seguras de cliente y servidor de socket TLS para ReactPHP.
Versión de desarrollo: esta rama contiene el código para la próxima versión v3. Para obtener el código de la versión estable v1 actual, consulte la rama
1.x
La próxima versión v3 será el camino a seguir para este paquete. Sin embargo, seguiremos admitiendo activamente la versión 1 para aquellos que aún no tengan la última versión. Consulte también las instrucciones de instalación para obtener más detalles.
La biblioteca de sockets proporciona interfaces reutilizables para un servidor y un cliente de capa de socket basados en los componentes EventLoop
y Stream
. Su componente de servidor le permite crear servidores de red que acepten conexiones entrantes de clientes de red (como un servidor HTTP). Su componente de cliente le permite crear clientes de red que establecen conexiones salientes a servidores de red (como un cliente HTTP o de base de datos). Esta biblioteca proporciona medios de transmisión asíncronos para todo esto, por lo que puede manejar múltiples conexiones simultáneas sin bloquearlas.
Tabla de contenido
Aquí hay un servidor que cierra la conexión si le envía algo:
$ 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 ();
});
});
Vea también los ejemplos.
Aquí hay un cliente que genera la salida de dicho servidor y luego intenta enviarle una cadena:
$ 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
se utiliza para representar cualquier conexión entrante y saliente, como una conexión TCP/IP normal.
Una conexión entrante o saliente es una transmisión dúplex (tanto legible como escribible) que implementa DuplexStreamInterface
de React. Contiene propiedades adicionales para la dirección local y remota (IP del cliente) donde se ha establecido esta conexión hacia/desde.
Por lo general, las instancias que implementan esta ConnectionInterface
son emitidas por todas las clases que implementan ServerInterface
y utilizadas por todas las clases que implementan ConnectorInterface
.
Debido a que ConnectionInterface
implementa la DuplexStreamInterface
subyacente, puedes usar cualquiera de sus eventos y métodos como de costumbre:
$ 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 ();
// …
Para obtener más detalles, consulte DuplexStreamInterface
.
El método getRemoteAddress(): ?string
devuelve la dirección remota completa (URI) donde se ha establecido esta conexión.
$ address = $ connection -> getRemoteAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Si la dirección remota no se puede determinar o es desconocida en este momento (por ejemplo, después de cerrar la conexión), PUEDE devolver un valor NULL
.
De lo contrario, devolverá la dirección completa (URI) como un valor de cadena, como tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
o unix:///path/to/example.sock
. Tenga en cuenta que los componentes de URI individuales son específicos de la aplicación y dependen del protocolo de transporte subyacente.
Si se trata de una conexión basada en TCP/IP y solo desea la IP remota, puede usar algo como esto:
$ address = $ connection -> getRemoteAddress ();
$ ip = trim ( parse_url ( $ address , PHP_URL_HOST ), ' [] ' );
echo ' Connection with ' . $ ip . PHP_EOL ;
El método getLocalAddress(): ?string
devuelve la dirección local completa (URI) donde se ha establecido esta conexión.
$ address = $ connection -> getLocalAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Si la dirección local no se puede determinar o es desconocida en este momento (por ejemplo, después de cerrar la conexión), PUEDE devolver un valor NULL
.
De lo contrario, devolverá la dirección completa (URI) como un valor de cadena, como tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
o unix:///path/to/example.sock
. Tenga en cuenta que los componentes de URI individuales son específicos de la aplicación y dependen del protocolo de transporte subyacente.
Este método complementa el método getRemoteAddress()
, por lo que no deben confundirse.
Si su instancia TcpServer
está escuchando en múltiples interfaces (por ejemplo, usando la dirección 0.0.0.0
), puede usar este método para averiguar qué interfaz aceptó realmente esta conexión (como una interfaz pública o local).
Si su sistema tiene varias interfaces (por ejemplo, una interfaz WAN y una LAN), puede utilizar este método para averiguar qué interfaz se utilizó realmente para esta conexión.
ServerInterface
es responsable de proporcionar una interfaz para aceptar conexiones de transmisión entrantes, como una conexión TCP/IP normal.
La mayoría de los componentes de nivel superior (como un servidor HTTP) aceptan una instancia que implementa esta interfaz para aceptar conexiones de transmisión entrantes. Esto generalmente se hace mediante inyección de dependencia, por lo que es bastante sencillo intercambiar esta implementación con cualquier otra implementación de esta interfaz. Esto significa que DEBE escribir en esta interfaz en lugar de una implementación concreta de esta interfaz.
Además de definir algunos métodos, esta interfaz también implementa EventEmitterInterface
que le permite reaccionar ante ciertos eventos.
El evento connection
se emitirá cada vez que se establezca una nueva conexión, es decir, un nuevo cliente se conecte a este socket de servidor:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' new connection ' . PHP_EOL ;
});
Consulte también ConnectionInterface
para obtener más detalles sobre cómo manejar la conexión entrante.
El evento error
se emitirá cada vez que haya un error al aceptar una nueva conexión de un cliente.
$ socket -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage () . PHP_EOL ;
});
Tenga en cuenta que este no es un evento de error fatal, es decir, el servidor sigue escuchando nuevas conexiones incluso después de este evento.
El método getAddress(): ?string
se puede utilizar para devolver la dirección completa (URI) que este servidor está escuchando actualmente.
$ address = $ socket -> getAddress ();
echo ' Server listening on ' . $ address . PHP_EOL ;
Si la dirección no se puede determinar o es desconocida en este momento (por ejemplo, después de cerrar el socket), PUEDE devolver un valor NULL
.
De lo contrario, devolverá la dirección completa (URI) como un valor de cadena, como tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
unix://example.sock
o unix:///path/to/example.sock
. Tenga en cuenta que los componentes de URI individuales son específicos de la aplicación y dependen del protocolo de transporte subyacente.
Si se trata de un servidor basado en TCP/IP y sólo desea el puerto local, puede utilizar algo como esto:
$ address = $ socket -> getAddress ();
$ port = parse_url ( $ address , PHP_URL_PORT );
echo ' Server listening on port ' . $ port . PHP_EOL ;
El método pause(): void
se puede utilizar para pausar la aceptación de nuevas conexiones entrantes.
Elimina el recurso de socket del EventLoop y así deja de aceptar nuevas conexiones. Tenga en cuenta que la toma de escucha permanece activa y no está cerrada.
Esto significa que las nuevas conexiones entrantes permanecerán pendientes en el trabajo pendiente del sistema operativo hasta que se complete su trabajo pendiente configurable. Una vez que se llena el trabajo pendiente, el sistema operativo puede rechazar más conexiones entrantes hasta que el trabajo pendiente se agote nuevamente al reanudar la aceptación de nuevas conexiones.
Una vez que el servidor está en pausa, no DEBEN emitirse más eventos connection
.
$ socket -> pause ();
$ socket -> on ( ' connection ' , assertShouldNeverCalled ());
Este método es solo de asesoramiento, aunque generalmente no se recomienda; el servidor PUEDE continuar emitiendo eventos connection
.
A menos que se indique lo contrario, un servidor abierto exitosamente NO DEBE iniciarse en estado de pausa.
Puede continuar procesando eventos llamando resume()
nuevamente.
Tenga en cuenta que ambos métodos se pueden llamar cualquier cantidad de veces; en particular, llamar pause()
más de una vez NO DEBE tener ningún efecto. De manera similar, llamar a esto después de close()
es NO-OP.
El método resume(): void
se puede utilizar para reanudar la aceptación de nuevas conexiones entrantes.
Vuelva a adjuntar el recurso de socket al EventLoop después de una pause()
anterior.
$ socket -> pause ();
Loop:: addTimer ( 1.0 , function () use ( $ socket ) {
$ socket -> resume ();
});
Tenga en cuenta que ambos métodos se pueden llamar cualquier cantidad de veces; en particular, llamar resume()
sin una pause()
NO DEBE tener ningún efecto. De manera similar, llamar a esto después de close()
es NO-OP.
El método close(): void
se puede utilizar para cerrar este conector de escucha.
Esto dejará de escuchar nuevas conexiones entrantes en este socket.
echo ' Shutting down server socket ' . PHP_EOL ;
$ socket -> close ();
Llamar a este método más de una vez en la misma instancia es NO-OP.
La clase SocketServer
es la clase principal de este paquete que implementa ServerInterface
y le permite aceptar conexiones de transmisión entrantes, como TCP/IP de texto sin formato o transmisiones de conexión TLS seguras.
Para aceptar conexiones TCP/IP de texto sin formato, simplemente puede pasar una combinación de host y puerto como esta:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
Escuchar en la dirección de host local 127.0.0.1
significa que no será posible acceder a ella desde fuera de este sistema. Para cambiar el host en el que escucha el socket, puede proporcionar una dirección IP de una interfaz o usar la dirección especial 0.0.0.0
para escuchar en todas las interfaces:
$ socket = new React Socket SocketServer ( ' 0.0.0.0:8080 ' );
Si desea escuchar en una dirección IPv6, DEBE incluir el host entre corchetes:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' );
Para utilizar una asignación de puerto aleatoria, puede utilizar el puerto 0
:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:0 ' );
$ address = $ socket -> getAddress ();
Para escuchar en una ruta de socket de dominio Unix (UDS), DEBE prefijar el URI con el esquema unix://
:
$ socket = new React Socket SocketServer ( ' unix:///tmp/server.sock ' );
Para escuchar un número de descriptor de archivo (FD) existente, DEBE prefijar el URI con php://fd/
como este:
$ socket = new React Socket SocketServer ( ' php://fd/3 ' );
Si el URI proporcionado no es válido, no contiene un puerto, ningún otro esquema o si contiene un nombre de host, generará una InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ socket = new React Socket SocketServer ( ' 127.0.0.1 ' );
Si el URI proporcionado parece ser válido, pero falla al escucharlo (por ejemplo, si el puerto ya está en uso o si el puerto inferior a 1024 puede requerir acceso de root, etc.), se generará una 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 ' );
Tenga en cuenta que estas condiciones de error pueden variar según su sistema y/o configuración. Consulte el mensaje y el código de excepción para obtener más detalles sobre la condición de error real.
Opcionalmente, puede especificar opciones de contexto de socket TCP para el recurso de socket de flujo subyacente de esta manera:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' , [
' tcp ' => [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]
]);
Tenga en cuenta que las opciones de contexto de socket disponibles, sus valores predeterminados y los efectos de cambiarlos pueden variar según su sistema y/o versión de PHP. Pasar opciones de contexto desconocidas no tiene ningún efecto. La opción de contexto
backlog
tiene como valor predeterminado511
a menos que se indique explícitamente.
Puede iniciar un servidor TLS (anteriormente conocido como SSL) seguro simplemente anteponiendo el esquema URI tls://
. Internamente, esperará conexiones TCP/IP de texto sin formato y luego realizará un protocolo de enlace TLS para cada conexión. Por lo tanto, requiere opciones de contexto TLS válidas, que en su forma más básica pueden verse así si está utilizando un archivo de certificado codificado PEM:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8080 ' , [
' tls ' => [
' local_cert ' => ' server.pem '
]
]);
Tenga en cuenta que el archivo de certificado no se cargará al crear una instancia, sino cuando una conexión entrante inicialice su contexto TLS. Esto implica que cualquier ruta o contenido de archivo de certificado no válido solo provocará un evento
error
en un momento posterior.
Si su clave privada está cifrada con una frase de contraseña, debe especificarla de esta manera:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]
]);
De forma predeterminada, este servidor admite TLSv1.0+ y excluye la compatibilidad con SSLv2/SSLv3 heredado. También puedes elegir explícitamente la versión de TLS que deseas negociar con el lado remoto:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_SERVER
]
]);
Tenga en cuenta que las opciones de contexto TLS disponibles, sus valores predeterminados y los efectos de cambiarlos pueden variar según su sistema y/o versión de PHP. La matriz de contexto externo le permite usar también opciones de contexto
tcp
(y posiblemente más) al mismo tiempo. Pasar opciones de contexto desconocidas no tiene ningún efecto. Si no utiliza el esquematls://
, pasar las opciones de contextotls
no tiene ningún efecto.
Cada vez que un cliente se conecta, emitirá un evento connection
con una instancia de conexión que implementa ConnectionInterface
:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte también ServerInterface
para obtener más detalles.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
Tenga en cuenta que la clase
SocketServer
es una implementación concreta para sockets TCP/IP. Si desea escribir sugerencias en la implementación de su protocolo de nivel superior, DEBE usar laServerInterface
genérica en su lugar.
La clase TcpServer
implementa ServerInterface
y es responsable de aceptar conexiones TCP/IP de texto sin formato.
$ server = new React Socket TcpServer ( 8080 );
Como se indicó anteriormente, el parámetro $uri
puede consistir solo en un puerto, en cuyo caso el servidor escuchará de forma predeterminada en la dirección de host local 127.0.0.1
, lo que significa que no será accesible desde fuera de este sistema.
Para utilizar una asignación de puerto aleatoria, puede utilizar el puerto 0
:
$ server = new React Socket TcpServer ( 0 );
$ address = $ server -> getAddress ();
Para cambiar el host en el que escucha el socket, puede proporcionar una dirección IP a través del primer parámetro proporcionado al constructor, opcionalmente precedido por el esquema tcp://
:
$ server = new React Socket TcpServer ( ' 192.168.0.1:8080 ' );
Si desea escuchar en una dirección IPv6, DEBE incluir el host entre corchetes:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' );
Si el URI proporcionado no es válido, no contiene un puerto, ningún otro esquema o si contiene un nombre de host, generará una InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ server = new React Socket TcpServer ( ' 127.0.0.1 ' );
Si el URI proporcionado parece ser válido, pero falla al escucharlo (por ejemplo, si el puerto ya está en uso o si el puerto inferior a 1024 puede requerir acceso de root, etc.), se generará una RuntimeException
:
$ first = new React Socket TcpServer ( 8080 );
// throws RuntimeException because port is already in use
$ second = new React Socket TcpServer ( 8080 );
Tenga en cuenta que estas condiciones de error pueden variar según su sistema y/o configuración. Consulte el mensaje y el código de excepción para obtener más detalles sobre la condición de error real.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
Opcionalmente, puede especificar opciones de contexto de socket para el recurso de socket de flujo subyacente de esta manera:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' , null , [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]);
Tenga en cuenta que las opciones de contexto de socket disponibles, sus valores predeterminados y los efectos de cambiarlos pueden variar según su sistema y/o versión de PHP. Pasar opciones de contexto desconocidas no tiene ningún efecto. La opción de contexto
backlog
tiene como valor predeterminado511
a menos que se indique explícitamente.
Cada vez que un cliente se conecta, emitirá un evento connection
con una instancia de conexión que implementa ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte también ServerInterface
para obtener más detalles.
La clase SecureServer
implementa ServerInterface
y es responsable de proporcionar un servidor TLS (anteriormente conocido como SSL) seguro.
Lo hace envolviendo una instancia TcpServer
que espera conexiones TCP/IP de texto sin formato y luego realiza un protocolo de enlace TLS para cada conexión. Por lo tanto, requiere opciones de contexto TLS válidas, que en su forma más básica pueden verse así si está utilizando un archivo de certificado codificado PEM:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem '
]);
Tenga en cuenta que el archivo de certificado no se cargará al crear una instancia, sino cuando una conexión entrante inicialice su contexto TLS. Esto implica que cualquier ruta o contenido de archivo de certificado no válido solo provocará un evento
error
en un momento posterior.
Si su clave privada está cifrada con una frase de contraseña, debe especificarla de esta manera:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]);
De forma predeterminada, este servidor admite TLSv1.0+ y excluye la compatibilidad con SSLv2/SSLv3 heredado. También puedes elegir explícitamente la versión de TLS que deseas negociar con el lado remoto:
$ 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
]);
Tenga en cuenta que las opciones de contexto TLS disponibles, sus valores predeterminados y los efectos de cambiarlos pueden variar según su sistema y/o versión de PHP. Pasar opciones de contexto desconocidas no tiene ningún efecto.
Cada vez que un cliente completa el protocolo de enlace TLS, emitirá un evento connection
con una instancia de conexión que implementa ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Secure connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Siempre que un cliente no pueda realizar un protocolo de enlace TLS exitoso, emitirá un evento error
y luego cerrará la conexión TCP/IP subyacente:
$ server -> on ( ' error ' , function ( Exception $ e ) {
echo ' Error ' . $ e -> getMessage () . PHP_EOL ;
});
Consulte también ServerInterface
para obtener más detalles.
Tenga en cuenta que la clase SecureServer
es una implementación concreta para sockets TLS. Si desea escribir sugerencias en la implementación de su protocolo de nivel superior, DEBE usar la ServerInterface
genérica en su lugar.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
Uso avanzado: a pesar de permitir cualquier
ServerInterface
como primer parámetro, DEBE pasar una instanciaTcpServer
como primer parámetro, a menos que sepa lo que está haciendo. Internamente,SecureServer
debe configurar las opciones de contexto TLS requeridas en los recursos de flujo subyacentes. Estos recursos no están expuestos a través de ninguna de las interfaces definidas en este paquete, sino solo a través de la claseConnection
interna. Se garantiza que la claseTcpServer
emitirá conexiones que implementanConnectionInterface
y utiliza la claseConnection
interna para exponer estos recursos subyacentes. Si utiliza unaServerInterface
personalizada y su eventoconnection
no cumple con este requisito,SecureServer
emitirá un eventoerror
y luego cerrará la conexión subyacente.
La clase UnixServer
implementa ServerInterface
y es responsable de aceptar conexiones en sockets de dominio Unix (UDS).
$ server = new React Socket UnixServer ( ' /tmp/server.sock ' );
Como se indicó anteriormente, el parámetro $uri
puede consistir únicamente en una ruta de socket o una ruta de socket con el prefijo unix://
esquema.
Si el URI proporcionado parece ser válido, pero falla al escucharlo (por ejemplo, si el socket ya está en uso o no se puede acceder al archivo, etc.), se generará una 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 ' );
Tenga en cuenta que estas condiciones de error pueden variar según su sistema y/o configuración. En particular, Zend PHP sólo informa "Error desconocido" cuando la ruta UDS ya existe y no se puede vincular. Es posible que desee marcar
is_file()
en la ruta UDS proporcionada para informar un mensaje de error más fácil de usar en este caso. Consulte el mensaje y el código de excepción para obtener más detalles sobre la condición de error real.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
Cada vez que un cliente se conecta, emitirá un evento connection
con una instancia de conexión que implementa ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' New connection ' . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte también ServerInterface
para obtener más detalles.
El decorador LimitingServer
envuelve una ServerInterface
determinada y es responsable de limitar y realizar un seguimiento de las conexiones abiertas a esta instancia de servidor.
Cada vez que el servidor subyacente emite un evento connection
, comprobará sus límites y luego
connection
error
.Cada vez que se cierra una conexión, se eliminará de la lista de conexiones abiertas.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte también el segundo ejemplo para obtener más detalles.
Debe pasar un número máximo de conexiones abiertas para garantizar que el servidor rechace (cierre) automáticamente las conexiones una vez que se exceda este límite. En este caso emitirá un evento error
para informar de ello y no se emitirá ningún evento connection
.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
PUEDE pasar un límite null
para no poner límite a la cantidad de conexiones abiertas y seguir aceptando nuevas conexiones hasta que se quede sin recursos del sistema operativo (como identificadores de archivos abiertos). Esto puede resultar útil si no desea encargarse de aplicar un límite pero aún desea utilizar el método getConnections()
.
Opcionalmente, puede configurar el servidor para que haga una pausa en la aceptación de nuevas conexiones una vez que se alcance el límite de conexiones. En este caso, pausará el servidor subyacente y ya no procesará ninguna conexión nueva, por lo que tampoco cerrará ninguna conexión excesiva. El sistema operativo subyacente es responsable de mantener una acumulación de conexiones pendientes hasta que se alcanza su límite, momento en el que comenzará a rechazar más conexiones. Una vez que el servidor esté por debajo del límite de conexiones, continuará consumiendo conexiones del trabajo pendiente y procesará los datos pendientes en cada conexión. Este modo puede ser útil para algunos protocolos que están diseñados para esperar un mensaje de respuesta (como HTTP), pero puede ser menos útil para otros protocolos que exigen respuestas inmediatas (como un mensaje de "bienvenida" en un chat interactivo).
$ server = new React Socket LimitingServer ( $ server , 100 , true );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
El método getConnections(): ConnectionInterface[]
se puede utilizar para devolver una matriz con todas las conexiones actualmente activas.
foreach ( $ server -> getConnection () as $ connection ) {
$ connection -> write ( ' Hi! ' );
}
ConnectorInterface
es responsable de proporcionar una interfaz para establecer conexiones de transmisión, como una conexión TCP/IP normal.
Esta es la interfaz principal definida en este paquete y se utiliza en todo el vasto ecosistema de React.
La mayoría de los componentes de nivel superior (como HTTP, bases de datos u otros clientes de servicios de red) aceptan una instancia que implementa esta interfaz para crear su conexión TCP/IP al servicio de red subyacente. Esto generalmente se hace mediante inyección de dependencia, por lo que es bastante sencillo intercambiar esta implementación con cualquier otra implementación de esta interfaz.
La interfaz sólo ofrece un único método:
El método connect(string $uri): PromiseInterface<ConnectionInterface>
se puede utilizar para crear una conexión de streaming a la dirección remota dada.
Devuelve una Promesa que se cumple con una secuencia que implementa ConnectionInterface
en caso de éxito o se rechaza con una Exception
si la conexión no se realiza correctamente:
$ connector -> connect ( ' google.com:443 ' )-> then (
function ( React Socket ConnectionInterface $ connection ) {
// connection successfully established
},
function ( Exception $ error ) {
// failed to connect due to $error
}
);
Consulte también ConnectionInterface
para obtener más detalles.
La Promesa devuelta DEBE implementarse de tal manera que pueda cancelarse cuando aún esté pendiente. Cancelar una promesa pendiente DEBE rechazar su valor con una Exception
. DEBE limpiar los recursos y referencias subyacentes según corresponda:
$ promise = $ connector -> connect ( $ uri );
$ promise -> cancel ();
La clase Connector
es la clase principal de este paquete que implementa ConnectorInterface
y le permite crear conexiones de transmisión.
Puede utilizar este conector para crear cualquier tipo de conexiones de streaming, como TCP/IP de texto sin formato, TLS seguro o flujos de conexión locales de Unix.
Se vincula al bucle de eventos principal y se puede utilizar así:
$ 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 ;
});
Para crear una conexión TCP/IP de texto plano, simplemente puede pasar una combinación de host y puerto como esta:
$ connector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Si no especifica un esquema de URI en el URI de destino, asumirá
tcp://
como valor predeterminado y establecerá una conexión TCP/IP de texto sin formato. Tenga en cuenta que las conexiones TCP/IP requieren una parte de host y puerto en el URI de destino como se indicó anteriormente; todos los demás componentes del URI son opcionales.
Para crear una conexión TLS segura, puede utilizar el esquema URI tls://
como este:
$ connector -> connect ( ' tls://www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Para crear una conexión de socket de dominio Unix local, puede utilizar el esquema URI unix://
como este:
$ connector -> connect ( ' unix:///tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
El método
getRemoteAddress()
devolverá la ruta del socket de dominio Unix (UDS) de destino tal como se proporciona al métodoconnect()
, incluido el esquemaunix://
, por ejemplounix:///tmp/demo.sock
. Lo más probable es que el métodogetLocalAddress()
devuelva un valornull
ya que este valor no es aplicable a las conexiones UDS aquí.
Debajo del capó, el Connector
se implementa como una fachada de nivel superior para los conectores de nivel inferior implementados en este paquete. Esto significa que también comparte todas sus características y detalles de implementación. Si desea escribir sugerencias en la implementación de su protocolo de nivel superior, DEBE usar la ConnectorInterface
genérica en su lugar.
A partir de v1.4.0
, la clase Connector
utiliza de forma predeterminada el algoritmo Happy Eyeballs para conectarse automáticamente a través de IPv4 o IPv6 cuando se proporciona un nombre de host. Esto intenta conectarse automáticamente utilizando IPv4 e IPv6 al mismo tiempo (prefiriendo IPv6), evitando así los problemas habituales que enfrentan los usuarios con conexiones o configuraciones imperfectas de IPv6. Si desea volver al comportamiento anterior de realizar solo una búsqueda de IPv4 y solo intentar una única conexión IPv4, puede configurar el Connector
de esta manera:
$ connector = new React Socket Connector ([
' happy_eyeballs ' => false
]);
De manera similar, también puede afectar el comportamiento de DNS predeterminado de la siguiente manera. La clase Connector
intentará detectar la configuración DNS de su sistema (y utiliza el servidor DNS público 8.8.8.8
de Google como alternativa si no puede determinar la configuración de su sistema) para resolver todos los nombres de host públicos en direcciones IP subyacentes de forma predeterminada. Si desea utilizar explícitamente un servidor DNS personalizado (como una retransmisión DNS local o un servidor DNS para toda la empresa), puede configurar el Connector
de esta manera:
$ connector = new React Socket Connector ([
' dns ' => ' 127.0.1.1 '
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Si no desea utilizar ningún solucionador de DNS y desea conectarse solo a direcciones IP, también puede configurar su Connector
de esta manera:
$ connector = new React Socket Connector ([
' dns ' => false
]);
$ connector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Avanzado: si necesita una instancia DNS ReactDnsResolverResolverInterface
personalizada, también puede configurar su Connector
de esta manera:
$ 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 ();
});
De forma predeterminada, los esquemas de URI tcp://
y tls://
utilizarán un valor de tiempo de espera que respete su configuración ini default_socket_timeout
(que por defecto es 60 segundos). Si desea un valor de tiempo de espera personalizado, simplemente puede pasarlo así:
$ connector = new React Socket Connector ([
' timeout ' => 10.0
]);
De manera similar, si no desea aplicar ningún tiempo de espera y dejar que el sistema operativo se encargue de esto, puede pasar un indicador booleano como este:
$ connector = new React Socket Connector ([
' timeout ' => false
]);
De forma predeterminada, el Connector
admite los esquemas URI tcp://
, tls://
y unix://
. Si desea prohibir explícitamente cualquiera de estos, simplemente puede pasar indicadores booleanos como este:
// 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://
y tls://
también aceptan opciones de contexto adicionales pasadas a los conectores subyacentes. Si desea pasar explícitamente opciones de contexto adicionales, simplemente puede pasar matrices de opciones de contexto como esta:
// 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 ();
});
De forma predeterminada, este conector admite TLSv1.0+ y excluye la compatibilidad con SSLv2/SSLv3 heredado. También puedes elegir explícitamente la versión de TLS que deseas negociar con el lado remoto:
$ connector = new React Socket Connector ([
' tls ' => [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]
]);
Para obtener más detalles sobre las opciones de contexto, consulte la documentación de PHP sobre las opciones de contexto de socket y las opciones de contexto SSL.
Avanzado: de forma predeterminada, el Connector
admite los esquemas de URI tcp://
, tls://
y unix://
. Para ello, configura automáticamente las clases de conector necesarias. Si desea pasar explícitamente conectores personalizados para cualquiera de estos, simplemente puede pasar una instancia que implemente ConnectorInterface
de esta manera:
$ 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 ();
});
Internamente, el conector
tcp://
siempre estará ajustado por el solucionador de DNS, a menos que desactive DNS como en el ejemplo anterior. En este caso, el conectortcp://
recibe el nombre de host real en lugar de solo la dirección IP resuelta y, por lo tanto, es responsable de realizar la búsqueda. Internamente, el conectortls://
creado automáticamente siempre envolverá el conectortcp://
subyacente para establecer la conexión TCP/IP de texto sin formato subyacente antes de habilitar el modo TLS seguro. Si desea utilizar un conectortcp://
subyacente personalizado solo para conexiones TLS seguras, puede pasar explícitamente un conectortls://
como el anterior. Internamente, los conectorestcp://
ytls://
siempre estarán ajustados porTimeoutConnector
, a menos que deshabilites los tiempos de espera como en el ejemplo anterior.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
La clase TcpConnector
implementa ConnectorInterface
y le permite crear conexiones TCP/IP de texto sin formato a cualquier combinación de puerto IP:
$ tcpConnector = new React Socket TcpConnector ();
$ tcpConnector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Vea también los ejemplos.
Los intentos de conexión pendientes se pueden cancelar cancelando su promesa pendiente de esta manera:
$ promise = $ tcpConnector -> connect ( ' 127.0.0.1:80 ' );
$ promise -> cancel ();
Llamar cancel()
en una promesa pendiente cerrará el recurso de socket subyacente, cancelando así la conexión TCP/IP pendiente y rechazará la promesa resultante.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
Opcionalmente, puedes pasar opciones de contexto de socket adicionales al constructor de esta manera:
$ tcpConnector = new React Socket TcpConnector ( null , [
' bindto ' => ' 192.168.0.1:0 '
]);
Tenga en cuenta que esta clase solo le permite conectarse a combinaciones de puertos IP. Si el URI proporcionado no es válido, no contiene una dirección IP ni un puerto válidos o contiene cualquier otro esquema, se rechazará con una InvalidArgumentException
:
Si el URI proporcionado parece ser válido, pero la conexión falla (por ejemplo, si el host remoto rechaza la conexión, etc.), se rechazará con una RuntimeException
.
Si desea conectarse a combinaciones de nombre de host y puerto, consulte también el siguiente capítulo.
Uso avanzado: internamente,
TcpConnector
asigna un recurso de contexto vacío para cada recurso de transmisión. Si el URI de destino contiene un parámetro de consultahostname
, su valor se utilizará para configurar el nombre del par TLS.SecureConnector
yDnsConnector
lo utilizan para verificar el nombre del par y también se puede utilizar si desea un nombre de par TLS personalizado.
La clase HappyEyeBallsConnector
implementa ConnectorInterface
y le permite crear conexiones TCP/IP de texto sin formato a cualquier combinación de nombre de host y puerto. Internamente implementa el algoritmo happy eyeballs de RFC6555
y RFC8305
para admitir nombres de host IPv6 e IPv4.
Lo hace decorando una instancia TcpConnector
determinada para que primero busque el nombre de dominio dado a través de DNS (si corresponde) y luego establezca la conexión TCP/IP subyacente a la dirección IP de destino resuelta.
Asegúrese de configurar su resolución DNS y el conector TCP subyacente de esta manera:
$ 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 ();
});
Vea también los ejemplos.
Los intentos de conexión pendientes se pueden cancelar cancelando su promesa pendiente de esta manera:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Llamar cancel()
en una promesa pendiente cancelará las búsquedas de DNS subyacentes y/o las conexiones TCP/IP subyacentes y rechazará la promesa resultante.
Esta clase toma un parámetro LoopInterface|null $loop
opcional que se puede usar para pasar la instancia del bucle de eventos para usar con este objeto. Puede utilizar un valor null
aquí para utilizar el bucle predeterminado. Este valor NO DEBE proporcionarse a menos que esté seguro de querer utilizar explícitamente una instancia de bucle de eventos determinada.
Uso avanzado: Internamente,
HappyEyeBallsConnector
se basa en unResolver
para buscar las direcciones IP para el nombre de host determinado. Luego reemplazará el nombre de host en el URI de destino con esta IP, agregará un parámetro de consultahostname
y pasará este URI actualizado al conector subyacente. El algoritmo Happy Eye Balls describe la búsqueda de direcciones IPv6 e IPv4 para el nombre de host dado, de modo que este conector envíe dos búsquedas de DNS para los registros A y AAAA. Luego utiliza todas las direcciones IP (tanto v6 como v4) e intenta conectarse a todas ellas con un intervalo de 50 ms entre ellas. Alteración entre direcciones IPv6 e IPv4. Cuando se establece una conexión, todas las demás búsquedas de DNS e intentos de conexión se cancelan.
La clase DnsConnector
implementa ConnectorInterface
y le permite crear conexiones TCP/IP de texto sin formato para cualquier combinación de nombre de host y puerto.
Lo hace decorando una instancia TcpConnector
determinada para que primero busque el nombre de dominio dado a través de DNS (si corresponde) y luego establezca la conexión TCP/IP subyacente a la dirección IP de destino resuelta.
Asegúrese de configurar su resolución DNS y el conector TCP subyacente de esta manera:
$ 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 ();
});
Vea también los ejemplos.
Los intentos de conexión pendientes se pueden cancelar cancelando su promesa pendiente de esta manera:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Llamar cancel()
en una promesa pendiente cancelará la búsqueda de DNS subyacente y/o la conexión TCP/IP subyacente y rechazará la promesa resultante.
Uso avanzado: Internamente,
DnsConnector
se basa enReactDnsResolverResolverInterface
para buscar la dirección IP para el nombre de host dado. Luego reemplazará el nombre de host en el URI de destino con esta IP, agregará un parámetro de consultahostname
y pasará este URI actualizado al conector subyacente. Por lo tanto, el conector subyacente es responsable de crear una conexión a la dirección IP de destino, mientras que este parámetro de consulta se puede usar para verificar el nombre de host original yTcpConnector
lo usa para configurar el nombre del par TLS. Si se proporciona unhostname
explícitamente, este parámetro de consulta no se modificará, lo que puede resultar útil si desea un nombre de igual TLS personalizado.
La clase SecureConnector
implementa ConnectorInterface
y le permite crear conexiones TLS (anteriormente conocidas como SSL) seguras para cualquier combinación de nombre de host y puerto.
Lo hace decorando una instancia DnsConnector
determinada para que primero cree una conexión TCP/IP de texto sin formato y luego habilite el cifrado TLS en esta secuencia.
$ 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" );
. . .
});
Vea también los ejemplos.
Los intentos de conexión pendientes se pueden cancelar cancelando su promesa pendiente como así:
$ promise = $ secureConnector -> connect ( ' www.google.com:443 ' );
$ promise -> cancel ();
Llamar cancel()
en una promesa pendiente cancelará la conexión TCP/IP subyacente y/o la negociación SSL/TLS y rechazará la promesa resultante.
Esta clase toma un parámetro opcional LoopInterface|null $loop
que se puede usar para pasar la instancia de bucle de eventos para usar para este objeto. Puede usar un valor null
aquí para usar el bucle predeterminado. No se debe dar este valor a menos que esté seguro de que desea usar explícitamente una instancia de bucle de eventos dada.
Opcionalmente, puede pasar opciones de contexto SSL adicionales al constructor así:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' verify_peer ' => false ,
' verify_peer_name ' => false
]);
Por defecto, este conector admite TLSV1.0+ y excluye el soporte para Legacy SSLV2/SSLV3. También puede elegir explícitamente la versión TLS que desea negociar con el lado remoto:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]);
Uso avanzado: internamente, el
SecureConnector
se basa en configurar las opciones de contexto requeridas en el recurso de transmisión subyacente. Por lo tanto, debe usarse con unTcpConnector
en algún lugar de la pila de conector para que pueda asignar un recurso de contexto vacío para cada recurso de flujo y verificar el nombre de la pareja. No hacerlo puede dar lugar a un error de desajuste de nombre de par de TLS o en algunas condiciones de carrera difíciles de rastrear, porque todos los recursos de flujo utilizarán un solo recurso de contexto predeterminado compartido de lo contrario.
La clase TimeoutConnector
implementa la ConnectorInterface
y le permite agregar el manejo del tiempo de espera a cualquier instancia del conector existente.
Lo hace decorando cualquier instancia de ConnectorInterface
dada e iniciando un temporizador que rechazará y abortará automáticamente cualquier intento de conexión subyacente si lleva demasiado tiempo.
$ 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
});
Ver también cualquiera de los ejemplos.
Esta clase toma un parámetro opcional LoopInterface|null $loop
que se puede usar para pasar la instancia de bucle de eventos para usar para este objeto. Puede usar un valor null
aquí para usar el bucle predeterminado. No se debe dar este valor a menos que esté seguro de que desea usar explícitamente una instancia de bucle de eventos dada.
Los intentos de conexión pendientes se pueden cancelar cancelando su promesa pendiente como así:
$ promise = $ timeoutConnector -> connect ( ' google.com:80 ' );
$ promise -> cancel ();
Llamar cancel()
en una promesa pendiente cancelará el intento de conexión subyacente, abortará el temporizador y rechazará la promesa resultante.
La clase UnixConnector
implementa la ConnectorInterface
y le permite conectarse a rutas de socket de dominio UNIX (UDS) como esta:
$ connector = new React Socket UnixConnector ();
$ connector -> connect ( ' /tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " HELLO n" );
});
Conectarse a los enchufes de dominio UNIX es una operación atómica, es decir, su promesa se resolverá (se resolverá o rechazará) de inmediato. Como tal, llamar cancel()
sobre la promesa resultante no tiene ningún efecto.
El método
getRemoteAddress()
devolverá la ruta de socket de dominio Unix de destino (UDS) como se da al métodoconnect()
, prepuesto con el esquemaunix://
, por ejemplounix:///tmp/demo.sock
. El métodogetLocalAddress()
probablemente devolverá un valornull
ya que este valor no es aplicable a las conexiones UDS aquí.
Esta clase toma un parámetro opcional LoopInterface|null $loop
que se puede usar para pasar la instancia de bucle de eventos para usar para este objeto. Puede usar un valor null
aquí para usar el bucle predeterminado. No se debe dar este valor a menos que esté seguro de que desea usar explícitamente una instancia de bucle de eventos dada.
La clase FixedUriConnector
implementa la ConnectorInterface
y decora un conector existente para usar siempre un URI fijo y preconfigurado.
Esto puede ser útil para los consumidores que no admiten ciertos URI, como cuando desea conectarse explícitamente a una ruta de enchufe de dominio UNIX (UDS) en lugar de conectarse a una dirección predeterminada asumida por una API de nivel superior:
$ 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 ' );
La forma recomendada de instalar esta biblioteca es a través de Composer. ¿Nuevo en el compositor?
Una vez lanzado, este proyecto seguirá a SemVer. Por el momento, esto instalará la última versión de desarrollo:
composer require react/socket:^3@dev
Consulte también el CHANGELOG para obtener detalles sobre las actualizaciones de versiones.
Este proyecto pretende ejecutarse en cualquier plataforma y, por lo tanto, no requiere ninguna extensión de PHP y admite la ejecución desde PHP 7.1 hasta PHP 8+ actual. Se recomienda encarecidamente utilizar la última versión de PHP compatible para este proyecto.
Legacy PHP <7.3.3 (y PHP <7.2.15) sufre de un error donde FEFOF () podría bloquear con el uso del 100% de CPU en registros TLS fragmentados. Tratamos de trabajar en torno a esto consumiendo siempre el búfer de recepción completo a la vez para evitar datos obsoletos en los búferes TLS. Se sabe que esto funciona con un alto uso de CPU para compañeros de bienestar, pero esto puede causar fragmentos de datos muy grandes para escenarios de alto rendimiento. El comportamiento de buggy aún se puede activar debido a los búferes de E/S de red o pares maliciosos en las versiones afectadas, se recomienda la actualización.
Legacy PHP <7.1.4 sufre de un error al escribir grandes fragmentos de datos sobre las transmisiones TLS a la vez. Tratamos de trabajar alrededor de esto limitando el tamaño de la fragmentación de escritura a 8192 bytes solo para versiones PHP más antiguas. Esto es solo una solución al trabajo y tiene una notable penalización de rendimiento en las versiones afectadas.
Para ejecutar el conjunto de pruebas, primero debe clonar este repositorio y luego instalar todas las dependencias a través de Composer:
composer install
Para ejecutar el conjunto de pruebas, vaya a la raíz del proyecto y ejecute:
vendor/bin/phpunit
El conjunto de pruebas también contiene una serie de pruebas de integración funcional que dependen de una conexión a Internet estable. Si no desea ejecutarlos, simplemente se pueden omitir así:
vendor/bin/phpunit --exclude-group internet
MIT, ver archivo de LICENCIA.