Assíncrono, streaming de TCP/IP de texto simples e conexões seguras de servidor e cliente de soquete TLS para ReactPHP.
Versão de desenvolvimento: esta ramificação contém o código para a próxima versão v3. Para o código da versão estável atual v1, verifique o branch
1.x
A próxima versão v3 será o caminho a seguir para este pacote. No entanto, ainda ofereceremos suporte ativo à v1 para aqueles que ainda não possuem a versão mais recente. Consulte também as instruções de instalação para obter mais detalhes.
A biblioteca de soquetes fornece interfaces reutilizáveis para um servidor e cliente de camada de soquete com base nos componentes EventLoop
e Stream
. Seu componente de servidor permite construir servidores de rede que aceitam conexões de entrada de clientes de rede (como um servidor HTTP). Seu componente cliente permite criar clientes de rede que estabelecem conexões de saída com servidores de rede (como HTTP ou cliente de banco de dados). Esta biblioteca fornece meios de streaming assíncronos para tudo isso, para que você possa lidar com várias conexões simultâneas sem bloqueio.
Índice
Aqui está um servidor que fecha a conexão se você enviar alguma coisa:
$ 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 ();
});
});
Veja também os exemplos.
Aqui está um cliente que gera a saída do referido servidor e depois tenta enviar uma string:
$ 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 ;
});
O ConnectionInterface
é usado para representar qualquer conexão de entrada e saída, como uma conexão TCP/IP normal.
Uma conexão de entrada ou saída é um fluxo duplex (legível e gravável) que implementa DuplexStreamInterface
do React. Ele contém propriedades adicionais para o endereço local e remoto (IP do cliente) de onde esta conexão foi estabelecida.
Mais comumente, as instâncias que implementam este ConnectionInterface
são emitidas por todas as classes que implementam o ServerInterface
e usadas por todas as classes que implementam o ConnectorInterface
.
Como o ConnectionInterface
implementa o DuplexStreamInterface
subjacente, você pode usar qualquer um de seus eventos e métodos normalmente:
$ 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 obter mais detalhes, consulte DuplexStreamInterface
.
O método getRemoteAddress(): ?string
retorna o endereço remoto completo (URI) onde esta conexão foi estabelecida.
$ address = $ connection -> getRemoteAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Se o endereço remoto não puder ser determinado ou for desconhecido neste momento (como após o fechamento da conexão), ele PODE retornar um valor NULL
.
Caso contrário, ele retornará o endereço completo (URI) como um valor de string, como tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
ou unix:///path/to/example.sock
. Observe que os componentes individuais do URI são específicos do aplicativo e dependem do protocolo de transporte subjacente.
Se esta for uma conexão baseada em TCP/IP e você quiser apenas o IP remoto, você pode usar algo assim:
$ address = $ connection -> getRemoteAddress ();
$ ip = trim ( parse_url ( $ address , PHP_URL_HOST ), ' [] ' );
echo ' Connection with ' . $ ip . PHP_EOL ;
O método getLocalAddress(): ?string
retorna o endereço local completo (URI) onde esta conexão foi estabelecida.
$ address = $ connection -> getLocalAddress ();
echo ' Connection with ' . $ address . PHP_EOL ;
Se o endereço local não puder ser determinado ou for desconhecido neste momento (como após o fechamento da conexão), ele PODE retornar um valor NULL
.
Caso contrário, ele retornará o endereço completo (URI) como um valor de string, como tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
, unix://example.sock
ou unix:///path/to/example.sock
. Observe que os componentes individuais do URI são específicos do aplicativo e dependem do protocolo de transporte subjacente.
Este método complementa o método getRemoteAddress()
, portanto, eles não devem ser confundidos.
Se sua instância TcpServer
estiver escutando em múltiplas interfaces (por exemplo, usando o endereço 0.0.0.0
), você pode usar este método para descobrir qual interface realmente aceitou esta conexão (como uma interface pública ou local).
Se o seu sistema tiver múltiplas interfaces (por exemplo, uma interface WAN e uma interface LAN), você pode usar este método para descobrir qual interface foi realmente usada para esta conexão.
O ServerInterface
é responsável por fornecer uma interface para aceitar conexões de streaming de entrada, como uma conexão TCP/IP normal.
A maioria dos componentes de nível superior (como um servidor HTTP) aceita uma instância que implementa esta interface para aceitar conexões de streaming de entrada. Isso geralmente é feito por meio de injeção de dependência, portanto é bastante simples trocar essa implementação por qualquer outra implementação dessa interface. Isso significa que você DEVE digitar essa interface em vez de uma implementação concreta dessa interface.
Além de definir alguns métodos, esta interface também implementa o EventEmitterInterface
que permite reagir a determinados eventos.
O evento connection
será emitido sempre que uma nova conexão for estabelecida, ou seja, um novo cliente se conectar a este soquete do servidor:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' new connection ' . PHP_EOL ;
});
Consulte também ConnectionInterface
para obter mais detalhes sobre como lidar com a conexão de entrada.
O evento error
será emitido sempre que houver um erro ao aceitar uma nova conexão de um cliente.
$ socket -> on ( ' error ' , function ( Exception $ e ) {
echo ' error: ' . $ e -> getMessage () . PHP_EOL ;
});
Observe que este não é um evento de erro fatal, ou seja, o servidor continua escutando novas conexões mesmo após este evento.
O método getAddress(): ?string
pode ser usado para retornar o endereço completo (URI) que este servidor está escutando no momento.
$ address = $ socket -> getAddress ();
echo ' Server listening on ' . $ address . PHP_EOL ;
Se o endereço não puder ser determinado ou for desconhecido neste momento (como após o fechamento do soquete), ele PODE retornar um valor NULL
.
Caso contrário, ele retornará o endereço completo (URI) como um valor de string, como tcp://127.0.0.1:8080
, tcp://[::1]:80
, tls://127.0.0.1:443
unix://example.sock
ou unix:///path/to/example.sock
. Observe que os componentes individuais do URI são específicos do aplicativo e dependem do protocolo de transporte subjacente.
Se este for um servidor baseado em TCP/IP e você quiser apenas a porta local, você pode usar algo assim:
$ address = $ socket -> getAddress ();
$ port = parse_url ( $ address , PHP_URL_PORT );
echo ' Server listening on port ' . $ port . PHP_EOL ;
O método pause(): void
pode ser usado para pausar a aceitação de novas conexões de entrada.
Remove o recurso de soquete do EventLoop e, assim, deixa de aceitar novas conexões. Observe que o soquete de escuta permanece ativo e não está fechado.
Isso significa que novas conexões de entrada permanecerão pendentes no backlog do sistema operacional até que seu backlog configurável seja preenchido. Depois que o backlog for preenchido, o sistema operacional poderá rejeitar novas conexões de entrada até que o backlog seja esgotado novamente, retomando a aceitação de novas conexões.
Depois que o servidor estiver pausado, nenhum outro evento connection
DEVE ser emitido.
$ socket -> pause ();
$ socket -> on ( ' connection ' , assertShouldNeverCalled ());
Este método é apenas consultivo, embora geralmente não seja recomendado, o servidor PODE continuar emitindo eventos connection
.
Salvo indicação em contrário, um servidor aberto com sucesso NÃO DEVE iniciar em estado de pausa.
Você pode continuar processando eventos chamando resume()
novamente.
Observe que ambos os métodos podem ser chamados quantas vezes quiser, em particular chamar pause()
mais de uma vez NÃO DEVE ter nenhum efeito. Da mesma forma, chamar isso depois de close()
é NO-OP.
O método resume(): void
pode ser usado para retomar a aceitação de novas conexões de entrada.
Anexe novamente o recurso de soquete ao EventLoop após um pause()
anterior.
$ socket -> pause ();
Loop:: addTimer ( 1.0 , function () use ( $ socket ) {
$ socket -> resume ();
});
Observe que ambos os métodos podem ser chamados quantas vezes quiser, em particular chamar resume()
sem um pause()
prévio NÃO DEVE ter nenhum efeito. Da mesma forma, chamar isso depois de close()
é NO-OP.
O método close(): void
pode ser usado para desligar este soquete de escuta.
Isso interromperá a escuta de novas conexões de entrada neste soquete.
echo ' Shutting down server socket ' . PHP_EOL ;
$ socket -> close ();
Chamar esse método mais de uma vez na mesma instância é NO-OP.
A classe SocketServer
é a classe principal neste pacote que implementa o ServerInterface
e permite aceitar conexões de streaming de entrada, como TCP/IP de texto simples ou fluxos de conexão TLS seguros.
Para aceitar conexões TCP/IP de texto simples, você pode simplesmente passar uma combinação de host e porta como esta:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:8080 ' );
Ouvir o endereço localhost 127.0.0.1
significa que ele não poderá ser acessado de fora deste sistema. Para alterar o host em que o soquete está escutando, você pode fornecer um endereço IP de uma interface ou usar o endereço especial 0.0.0.0
para escutar em todas as interfaces:
$ socket = new React Socket SocketServer ( ' 0.0.0.0:8080 ' );
Se quiser escutar um endereço IPv6, você DEVE colocar o host entre colchetes:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' );
Para usar uma atribuição de porta aleatória, você pode usar a porta 0
:
$ socket = new React Socket SocketServer ( ' 127.0.0.1:0 ' );
$ address = $ socket -> getAddress ();
Para escutar um caminho de soquete de domínio Unix (UDS), você DEVE prefixar o URI com o esquema unix://
:
$ socket = new React Socket SocketServer ( ' unix:///tmp/server.sock ' );
Para escutar um número de descritor de arquivo (FD) existente, você DEVE prefixar o URI com php://fd/
assim:
$ socket = new React Socket SocketServer ( ' php://fd/3 ' );
Se o URI fornecido for inválido, não contiver uma porta, qualquer outro esquema ou se contiver um nome de host, será lançada uma InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ socket = new React Socket SocketServer ( ' 127.0.0.1 ' );
Se o URI fornecido parecer válido, mas a escuta falhar (como se a porta já estiver em uso ou a porta abaixo de 1024 puder exigir acesso root, etc.), ele lançará uma 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 ' );
Observe que essas condições de erro podem variar dependendo do seu sistema e/ou configuração. Consulte a mensagem e o código de exceção para obter mais detalhes sobre a condição de erro real.
Opcionalmente, você pode especificar opções de contexto de soquete TCP para o recurso de soquete de fluxo subjacente como este:
$ socket = new React Socket SocketServer ( ' [::1]:8080 ' , [
' tcp ' => [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]
]);
Observe que as opções de contexto de soquete disponíveis, seus padrões e os efeitos de alterá-los podem variar dependendo do seu sistema e/ou versão do PHP. Passar opções de contexto desconhecidas não tem efeito. A opção de contexto
backlog
é padronizada como511
a menos que seja fornecida explicitamente.
Você pode iniciar um servidor TLS seguro (anteriormente conhecido como SSL) simplesmente acrescentando o esquema URI tls://
. Internamente, ele aguardará conexões TCP/IP de texto simples e, em seguida, executará um handshake TLS para cada conexão. Portanto, são necessárias opções de contexto TLS válidas, que em sua forma mais básica podem ser parecidas com isto se você estiver usando um arquivo de certificado codificado em PEM:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8080 ' , [
' tls ' => [
' local_cert ' => ' server.pem '
]
]);
Observe que o arquivo de certificado não será carregado na instanciação, mas quando uma conexão de entrada inicializar seu contexto TLS. Isso implica que qualquer caminho ou conteúdo de arquivo de certificado inválido só causará um evento
error
posteriormente.
Se sua chave privada estiver criptografada com uma senha, você deverá especificá-la assim:
$ socket = new React Socket SocketServer ( ' tls://127.0.0.1:8000 ' , [
' tls ' => [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]
]);
Por padrão, este servidor oferece suporte a TLSv1.0+ e exclui suporte para SSLv2/SSLv3 legado. Você também pode escolher explicitamente a versão do TLS que deseja negociar com o 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
]
]);
Observe que as opções de contexto TLS disponíveis, seus padrões e os efeitos de alterá-los podem variar dependendo do seu sistema e/ou versão do PHP. A matriz de contexto externa permite que você também use opções de contexto
tcp
(e possivelmente mais) ao mesmo tempo. Passar opções de contexto desconhecidas não tem efeito. Se você não usar o esquematls://
, passar as opções de contextotls
não terá efeito.
Sempre que um cliente se conecta, ele emitirá um evento connection
com uma instância de conexão implementando ConnectionInterface
:
$ socket -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte também ServerInterface
para obter mais detalhes.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
Observe que a classe
SocketServer
é uma implementação concreta para soquetes TCP/IP. Se você deseja digitar sua implementação de protocolo de nível superior, você DEVE usar oServerInterface
genérico.
A classe TcpServer
implementa ServerInterface
e é responsável por aceitar conexões TCP/IP de texto simples.
$ server = new React Socket TcpServer ( 8080 );
Como acima, o parâmetro $uri
pode consistir apenas em uma porta; nesse caso, o servidor será padronizado para escutar no endereço localhost 127.0.0.1
, o que significa que não será acessível de fora deste sistema.
Para usar uma atribuição de porta aleatória, você pode usar a porta 0
:
$ server = new React Socket TcpServer ( 0 );
$ address = $ server -> getAddress ();
Para alterar o host em que o soquete está escutando, você pode fornecer um endereço IP através do primeiro parâmetro fornecido ao construtor, opcionalmente precedido pelo esquema tcp://
:
$ server = new React Socket TcpServer ( ' 192.168.0.1:8080 ' );
Se quiser escutar um endereço IPv6, você DEVE colocar o host entre colchetes:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' );
Se o URI fornecido for inválido, não contiver uma porta, qualquer outro esquema ou se contiver um nome de host, será lançada uma InvalidArgumentException
:
// throws InvalidArgumentException due to missing port
$ server = new React Socket TcpServer ( ' 127.0.0.1 ' );
Se o URI fornecido parecer válido, mas a escuta falhar (como se a porta já estiver em uso ou a porta abaixo de 1024 puder exigir acesso root, etc.), ele lançará uma RuntimeException
:
$ first = new React Socket TcpServer ( 8080 );
// throws RuntimeException because port is already in use
$ second = new React Socket TcpServer ( 8080 );
Observe que essas condições de erro podem variar dependendo do seu sistema e/ou configuração. Consulte a mensagem e o código de exceção para obter mais detalhes sobre a condição de erro real.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
Opcionalmente, você pode especificar opções de contexto de soquete para o recurso de soquete de fluxo subjacente como este:
$ server = new React Socket TcpServer ( ' [::1]:8080 ' , null , [
' backlog ' => 200 ,
' so_reuseport ' => true ,
' ipv6_v6only ' => true
]);
Observe que as opções de contexto de soquete disponíveis, seus padrões e os efeitos de alterá-los podem variar dependendo do seu sistema e/ou versão do PHP. Passar opções de contexto desconhecidas não tem efeito. A opção de contexto
backlog
é padronizada como511
a menos que seja fornecida explicitamente.
Sempre que um cliente se conecta, ele emitirá um evento connection
com uma instância de conexão implementando ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Plaintext connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte também ServerInterface
para obter mais detalhes.
A classe SecureServer
implementa ServerInterface
e é responsável por fornecer um servidor TLS seguro (anteriormente conhecido como SSL).
Isso é feito agrupando uma instância TcpServer
que aguarda conexões TCP/IP de texto simples e, em seguida, executa um handshake TLS para cada conexão. Portanto, são necessárias opções de contexto TLS válidas, que em sua forma mais básica podem ser parecidas com isto se você estiver usando um arquivo de certificado codificado em PEM:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem '
]);
Observe que o arquivo de certificado não será carregado na instanciação, mas quando uma conexão de entrada inicializar seu contexto TLS. Isso implica que qualquer caminho ou conteúdo de arquivo de certificado inválido só causará um evento
error
posteriormente.
Se sua chave privada estiver criptografada com uma senha, você deverá especificá-la assim:
$ server = new React Socket TcpServer ( 8000 );
$ server = new React Socket SecureServer ( $ server , null , [
' local_cert ' => ' server.pem ' ,
' passphrase ' => ' secret '
]);
Por padrão, este servidor oferece suporte a TLSv1.0+ e exclui suporte para SSLv2/SSLv3 legado. Você também pode escolher explicitamente a versão do TLS que deseja negociar com o 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
]);
Observe que as opções de contexto TLS disponíveis, seus padrões e os efeitos de alterá-los podem variar dependendo do seu sistema e/ou versão do PHP. Passar opções de contexto desconhecidas não tem efeito.
Sempre que um cliente concluir o handshake TLS, ele emitirá um evento connection
com uma instância de conexão implementando ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' Secure connection from ' . $ connection -> getRemoteAddress () . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Sempre que um cliente não consegue executar um handshake TLS bem-sucedido, ele emitirá um evento error
e fechará a conexão TCP/IP subjacente:
$ server -> on ( ' error ' , function ( Exception $ e ) {
echo ' Error ' . $ e -> getMessage () . PHP_EOL ;
});
Consulte também ServerInterface
para obter mais detalhes.
Observe que a classe SecureServer
é uma implementação concreta para soquetes TLS. Se você deseja digitar sua implementação de protocolo de nível superior, você DEVE usar o ServerInterface
genérico.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
Uso avançado: Apesar de permitir qualquer
ServerInterface
como primeiro parâmetro, você DEVE passar uma instânciaTcpServer
como primeiro parâmetro, a menos que saiba o que está fazendo. Internamente, oSecureServer
precisa definir as opções de contexto TLS necessárias nos recursos de fluxo subjacentes. Esses recursos não são expostos por meio de nenhuma interface definida neste pacote, mas apenas por meio da classeConnection
interna. A classeTcpServer
tem garantia de emitir conexões que implementam oConnectionInterface
e usa a classeConnection
interna para expor esses recursos subjacentes. Se você usar umServerInterface
personalizado e seu eventoconnection
não atender a esse requisito, oSecureServer
emitirá um eventoerror
e fechará a conexão subjacente.
A classe UnixServer
implementa ServerInterface
e é responsável por aceitar conexões em soquetes de domínio Unix (UDS).
$ server = new React Socket UnixServer ( ' /tmp/server.sock ' );
Como acima, o parâmetro $uri
pode consistir apenas em um caminho de soquete ou caminho de soquete prefixado pelo esquema unix://
.
Se o URI fornecido parecer válido, mas a escuta falhar (como se o soquete já estiver em uso ou o arquivo não estiver acessível, etc.), ele lançará uma 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 ' );
Observe que essas condições de erro podem variar dependendo do seu sistema e/ou configuração. Em particular, o Zend PHP apenas reporta “Erro desconhecido” quando o caminho UDS já existe e não pode ser vinculado. Você pode querer verificar
is_file()
no caminho UDS fornecido para relatar uma mensagem de erro mais amigável neste caso. Consulte a mensagem e o código de exceção para obter mais detalhes sobre a condição de erro real.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
Sempre que um cliente se conecta, ele emitirá um evento connection
com uma instância de conexão implementando ConnectionInterface
:
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
echo ' New connection ' . PHP_EOL ;
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Consulte também ServerInterface
para obter mais detalhes.
O decorador LimitingServer
envolve um determinado ServerInterface
e é responsável por limitar e manter o controle de conexões abertas com esta instância do servidor.
Sempre que o servidor subjacente emitir um evento connection
, ele verificará seus limites e então
connection
error
.Sempre que uma conexão for fechada, ela será removida da lista de conexões abertas.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Veja também o segundo exemplo para mais detalhes.
Você deve passar um número máximo de conexões abertas para garantir que o servidor rejeitará (fechará) conexões automaticamente quando esse limite for excedido. Neste caso emitirá um evento error
para informar sobre isso e nenhum evento connection
será emitido.
$ server = new React Socket LimitingServer ( $ server , 100 );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
Você PODE passar um limite null
para não limitar o número de conexões abertas e continuar aceitando novas conexões até ficar sem recursos do sistema operacional (como identificadores de arquivos abertos). Isso pode ser útil se você não quiser aplicar um limite, mas ainda quiser usar o método getConnections()
.
Opcionalmente, você pode configurar o servidor para pausar a aceitação de novas conexões quando o limite de conexão for atingido. Nesse caso, ele pausará o servidor subjacente e não processará mais nenhuma conexão nova, portanto, também não fechará mais nenhuma conexão excessiva. O sistema operacional subjacente é responsável por manter um backlog de conexões pendentes até que seu limite seja atingido, momento em que começará a rejeitar novas conexões. Quando o servidor estiver abaixo do limite de conexão, ele continuará consumindo conexões do backlog e processará quaisquer dados pendentes em cada conexão. Este modo pode ser útil para alguns protocolos projetados para aguardar uma mensagem de resposta (como HTTP), mas pode ser menos útil para outros protocolos que exigem respostas imediatas (como uma mensagem de "boas-vindas" em um bate-papo interativo).
$ server = new React Socket LimitingServer ( $ server , 100 , true );
$ server -> on ( ' connection ' , function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' hello there! ' . PHP_EOL );
…
});
O método getConnections(): ConnectionInterface[]
pode ser usado para retornar um array com todas as conexões atualmente ativas.
foreach ( $ server -> getConnection () as $ connection ) {
$ connection -> write ( ' Hi! ' );
}
O ConnectorInterface
é responsável por fornecer uma interface para estabelecer conexões de streaming, como uma conexão TCP/IP normal.
Esta é a interface principal definida neste pacote e é usada em todo o vasto ecossistema do React.
A maioria dos componentes de nível superior (como HTTP, banco de dados ou outros clientes de serviços de rede) aceita uma instância que implementa essa interface para criar sua conexão TCP/IP com o serviço de rede subjacente. Isso geralmente é feito por meio de injeção de dependência, portanto é bastante simples trocar essa implementação por qualquer outra implementação dessa interface.
A interface oferece apenas um único método:
O método connect(string $uri): PromiseInterface<ConnectionInterface>
pode ser usado para criar uma conexão de streaming para o endereço remoto fornecido.
Ele retorna uma promessa que cumpre com um fluxo implementando ConnectionInterface
em caso de sucesso ou rejeita com uma Exception
se a conexão não for bem-sucedida:
$ connector -> connect ( ' google.com:443 ' )-> then (
function ( React Socket ConnectionInterface $ connection ) {
// connection successfully established
},
function ( Exception $ error ) {
// failed to connect due to $error
}
);
Consulte também ConnectionInterface
para obter mais detalhes.
A promessa retornada DEVE ser implementada de forma que possa ser cancelada quando ainda estiver pendente. Cancelar uma promessa pendente DEVE rejeitar seu valor com uma Exception
. DEVE limpar quaisquer recursos e referências subjacentes, conforme aplicável:
$ promise = $ connector -> connect ( $ uri );
$ promise -> cancel ();
A classe Connector
é a classe principal neste pacote que implementa o ConnectorInterface
e permite criar conexões de streaming.
Você pode usar esse conector para criar qualquer tipo de conexão de streaming, como TCP/IP de texto simples, TLS seguro ou fluxos de conexão Unix local.
Ele se liga ao loop de eventos principal e pode ser usado assim:
$ 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 criar uma conexão TCP/IP de texto simples, você pode simplesmente passar uma combinação de host e porta como esta:
$ connector -> connect ( ' www.google.com:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Se você não especificar um esquema de URI no URI de destino, ele assumirá
tcp://
como padrão e estabelecerá uma conexão TCP/IP de texto simples. Observe que as conexões TCP/IP requerem uma parte de host e porta no URI de destino como acima, todos os outros componentes do URI são opcionais.
Para criar uma conexão TLS segura, você pode usar o esquema de URI tls://
assim:
$ connector -> connect ( ' tls://www.google.com:443 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Para criar uma conexão de soquete de domínio Unix local, você pode usar o esquema URI unix://
como este:
$ connector -> connect ( ' unix:///tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
O método
getRemoteAddress()
retornará o caminho do soquete de domínio Unix (UDS) de destino conforme fornecido ao métodoconnect()
, incluindo o esquemaunix://
, por exemplounix:///tmp/demo.sock
. O métodogetLocalAddress()
provavelmente retornará um valornull
, pois este valor não é aplicável a conexões UDS aqui.
Nos bastidores, o Connector
é implementado como uma fachada de nível superior para os conectores de nível inferior implementados neste pacote. Isso significa que ele também compartilha todos os seus recursos e detalhes de implementação. Se você deseja digitar sua implementação de protocolo de nível superior, você DEVE usar o ConnectorInterface
genérico.
A partir da v1.4.0
, o padrão da classe Connector
é usar o algoritmo happy eyeballs para conectar-se automaticamente por IPv4 ou IPv6 quando um nome de host é fornecido. Isso tenta conectar-se automaticamente usando IPv4 e IPv6 ao mesmo tempo (preferindo IPv6), evitando assim os problemas habituais enfrentados por usuários com conexões ou configurações IPv6 imperfeitas. Se quiser reverter ao antigo comportamento de fazer apenas uma pesquisa IPv4 e tentar apenas uma única conexão IPv4, você pode configurar o Connector
assim:
$ connector = new React Socket Connector ([
' happy_eyeballs ' => false
]);
Da mesma forma, você também pode afetar o comportamento padrão do DNS da seguinte maneira. A classe Connector
tentará detectar as configurações de DNS do seu sistema (e usará o servidor DNS público 8.8.8.8
do Google como substituto se não for possível determinar as configurações do seu sistema) para resolver todos os nomes de host públicos em endereços IP subjacentes por padrão. Se você quiser usar explicitamente um servidor DNS personalizado (como uma retransmissão DNS local ou um servidor DNS para toda a empresa), poderá configurar o Connector
assim:
$ connector = new React Socket Connector ([
' dns ' => ' 127.0.1.1 '
]);
$ connector -> connect ( ' localhost:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Se você não quiser usar um resolvedor DNS e quiser se conectar apenas a endereços IP, você também pode configurar seu Connector
assim:
$ connector = new React Socket Connector ([
' dns ' => false
]);
$ connector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Avançado: se precisar de uma instância DNS ReactDnsResolverResolverInterface
personalizada, você também pode configurar seu Connector
assim:
$ 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 ();
});
Por padrão, os esquemas de URI tcp://
e tls://
usarão um valor de tempo limite que respeita sua configuração ini default_socket_timeout
(cujo padrão é 60s). Se você quiser um valor de tempo limite personalizado, basta passar assim:
$ connector = new React Socket Connector ([
' timeout ' => 10.0
]);
Da mesma forma, se você não quiser aplicar um tempo limite e deixar o sistema operacional cuidar disso, você pode passar um sinalizador booleano como este:
$ connector = new React Socket Connector ([
' timeout ' => false
]);
Por padrão, o Connector
suporta os esquemas de URI tcp://
, tls://
e unix://
. Se você quiser proibir explicitamente qualquer um deles, você pode simplesmente passar sinalizadores booleanos como estes:
// 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 ();
});
O tcp://
e tls://
também aceitam opções de contexto adicionais passadas para os conectores subjacentes. Se quiser passar explicitamente opções de contexto adicionais, você pode simplesmente passar matrizes de opções 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 ();
});
Por padrão, esse conector dá suporte a TLSv1.0+ e exclui suporte para SSLv2/SSLv3 herdado. Você também pode escolher explicitamente a versão do TLS que deseja negociar com o lado remoto:
$ connector = new React Socket Connector ([
' tls ' => [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]
]);
Para obter mais detalhes sobre opções de contexto, consulte a documentação do PHP sobre opções de contexto de soquete e opções de contexto SSL.
Avançado: por padrão, o Connector
suporta os esquemas de URI tcp://
, tls://
e unix://
. Para isso, ele configura automaticamente as classes de conectores necessárias. Se quiser passar explicitamente conectores personalizados para qualquer um deles, você pode simplesmente passar uma instância implementando o ConnectorInterface
assim:
$ 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, o conector
tcp://
sempre será encapsulado pelo resolvedor DNS, a menos que você desabilite o DNS como no exemplo acima. Nesse caso, o conectortcp://
recebe o nome do host real em vez de apenas o endereço IP resolvido e é, portanto, responsável por realizar a pesquisa. Internamente, o conectortls://
criado automaticamente sempre envolverá o conectortcp://
subjacente para estabelecer a conexão TCP/IP de texto simples subjacente antes de ativar o modo TLS seguro. Se quiser usar um conectortcp://
subjacente personalizado apenas para conexões TLS seguras, você pode passar explicitamente um conectortls://
como acima. Internamente, os conectorestcp://
etls://
sempre serão encapsulados porTimeoutConnector
, a menos que você desabilite os tempos limite como no exemplo acima.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
A classe TcpConnector
implementa ConnectorInterface
e permite criar conexões TCP/IP de texto simples para qualquer combinação de porta IP:
$ tcpConnector = new React Socket TcpConnector ();
$ tcpConnector -> connect ( ' 127.0.0.1:80 ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( ' ... ' );
$ connection -> end ();
});
Veja também os exemplos.
As tentativas de conexão pendentes podem ser canceladas cancelando sua promessa pendente da seguinte forma:
$ promise = $ tcpConnector -> connect ( ' 127.0.0.1:80 ' );
$ promise -> cancel ();
Chamar cancel()
em uma promessa pendente fechará o recurso de soquete subjacente, cancelando assim a conexão TCP/IP pendente e rejeitando a promessa resultante.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
Opcionalmente, você pode passar opções adicionais de contexto de soquete para o construtor assim:
$ tcpConnector = new React Socket TcpConnector ( null , [
' bindto ' => ' 192.168.0.1:0 '
]);
Observe que esta classe só permite que você se conecte a combinações de portas IP. Se o URI fornecido for inválido, não contiver um endereço IP e porta válidos ou contiver qualquer outro esquema, ele será rejeitado com uma InvalidArgumentException
:
Se o URI fornecido parecer válido, mas a conexão com ele falhar (como se o host remoto rejeitar a conexão, etc.), ele será rejeitado com uma RuntimeException
.
Se você deseja se conectar a combinações de hostname-port, consulte também o capítulo seguinte.
Uso avançado: Internamente, o
TcpConnector
aloca um recurso de contexto vazio para cada recurso de fluxo. Se o URI de destino contiver um parâmetro de consultahostname
, seu valor será usado para configurar o nome do peer TLS. Isso é usado peloSecureConnector
eDnsConnector
para verificar o nome do peer e também pode ser usado se você desejar um nome de peer TLS personalizado.
A classe HappyEyeBallsConnector
implementa o ConnectorInterface
e permite criar conexões TCP/IP de texto simples para qualquer combinação de nome de host-porta. Internamente, ele implementa o algoritmo happy eyeballs de RFC6555
e RFC8305
para suportar nomes de host IPv6 e IPv4.
Ele faz isso decorando uma determinada instância TcpConnector
para que primeiro procure o nome de domínio fornecido via DNS (se aplicável) e, em seguida, estabeleça a conexão TCP/IP subjacente ao endereço IP de destino resolvido.
Certifique-se de configurar seu resolvedor DNS e o conector TCP subjacente assim:
$ 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 ();
});
Veja também os exemplos.
As tentativas de conexão pendentes podem ser canceladas cancelando sua promessa pendente da seguinte forma:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Chamar cancel()
em uma promessa pendente cancelará as pesquisas de DNS subjacentes e/ou a(s) conexão(ões) TCP/IP subjacente(s) e rejeitará a promessa resultante.
Esta classe usa um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar a instância do loop de eventos a ser usada para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Este valor NÃO DEVE ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de eventos.
Uso avançado: Internamente, o
HappyEyeBallsConnector
depende de umResolver
para procurar os endereços IP do nome de host fornecido. Em seguida, ele substituirá o nome do host no URI de destino por esses IPs e anexará um parâmetro de consultahostname
e passará esse URI atualizado para o conector subjacente. O algoritmo Happy Eye Balls descreve a procura do endereço IPv6 e IPv4 para o nome de host fornecido, de modo que esse conector envie duas pesquisas de DNS para os registros A e AAAA. Em seguida, ele usa todos os endereços IP (v6 e v4) e tenta se conectar a todos eles com um intervalo de 50 ms entre eles. Alterando entre endereços IPv6 e IPv4. Quando uma conexão é estabelecida, todas as outras pesquisas de DNS e tentativas de conexão são canceladas.
A classe DnsConnector
implementa o ConnectorInterface
e permite criar conexões TCP/IP de texto simples para qualquer combinação de nome de host-porta.
Ele faz isso decorando uma determinada instância TcpConnector
para que primeiro procure o nome de domínio fornecido via DNS (se aplicável) e, em seguida, estabeleça a conexão TCP/IP subjacente ao endereço IP de destino resolvido.
Certifique-se de configurar seu resolvedor DNS e o conector TCP subjacente assim:
$ 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 ();
});
Veja também os exemplos.
As tentativas de conexão pendentes podem ser canceladas cancelando sua promessa pendente da seguinte forma:
$ promise = $ dnsConnector -> connect ( ' www.google.com:80 ' );
$ promise -> cancel ();
Chamar cancel()
em uma promessa pendente cancelará a pesquisa de DNS subjacente e/ou a conexão TCP/IP subjacente e rejeitará a promessa resultante.
Uso avançado: Internamente, o
DnsConnector
depende deReactDnsResolverResolverInterface
para procurar o endereço IP do nome de host fornecido. Em seguida, ele substituirá o nome do host no URI de destino por este IP e anexará um parâmetro de consultahostname
e passará esse URI atualizado para o conector subjacente. O conector subjacente é, portanto, responsável por criar uma conexão com o endereço IP de destino, enquanto este parâmetro de consulta pode ser usado para verificar o nome do host original e é usado peloTcpConnector
para configurar o nome do par TLS. Se umhostname
for fornecido explicitamente, esse parâmetro de consulta não será modificado, o que pode ser útil se você quiser um nome de peer TLS personalizado.
A classe SecureConnector
implementa o ConnectorInterface
e permite criar conexões TLS seguras (anteriormente conhecidas como SSL) para qualquer combinação de nome de host-porta.
Ele faz isso decorando uma determinada instância DnsConnector
para que primeiro crie uma conexão TCP/IP de texto simples e, em seguida, habilite a criptografia TLS nesse fluxo.
$ 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" );
. . .
});
Veja também os exemplos.
As tentativas de conexão pendentes podem ser canceladas cancelando sua promessa pendente como assim:
$ promise = $ secureConnector -> connect ( ' www.google.com:443 ' );
$ promise -> cancel ();
A chamada cancel()
em uma promessa pendente cancelará a conexão TCP/IP subjacente e/ou a negociação SSL/TLS e rejeitará a promessa resultante.
Esta classe leva um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar na instância do loop de evento para usar para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Esse valor não deve ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de evento.
Opcionalmente, você pode passar opções adicionais de contexto SSL para o construtor como este:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' verify_peer ' => false ,
' verify_peer_name ' => false
]);
Por padrão, esse conector suporta TLSV1.0+ e exclui o suporte ao legado SSLV2/SSLV3. Você também pode escolher explicitamente a versão TLS que deseja negociar com o lado remoto:
$ secureConnector = new React Socket SecureConnector ( $ dnsConnector , null , [
' crypto_method ' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
]);
Uso avançado: internamente, o
SecureConnector
conta com a configuração das opções de contexto necessárias no recurso de fluxo subjacente. Ele deve ser usado com umTcpConnector
em algum lugar da pilha do conector, para que possa alocar um recurso de contexto vazio para cada recurso de fluxo e verificar o nome do par. Não fazer isso pode resultar em um erro de incompatibilidade de nomes de pares TLS ou em algumas condições de corrida difícil de rastrear, porque todos os recursos do fluxo usarão um único recurso de contexto padrão compartilhado.
A classe TimeoutConnector
implementa o ConnectorInterface
e permite adicionar manuseio de tempo limite a qualquer instância do conector existente.
Faz isso decorando qualquer instância ConnectorInterface
e iniciando um temporizador que rejeitará e abortará automaticamente qualquer tentativa de conexão subjacente se demorar muito.
$ 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
});
Veja também qualquer um dos exemplos.
Esta classe leva um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar na instância do loop de evento para usar para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Esse valor não deve ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de evento.
As tentativas de conexão pendente podem ser canceladas cancelando sua promessa pendente como assim:
$ promise = $ timeoutConnector -> connect ( ' google.com:80 ' );
$ promise -> cancel ();
Chamando cancel()
em uma promessa pendente cancelará a tentativa de conexão subjacente, abortará o temporizador e rejeitará a promessa resultante.
A classe UnixConnector
implementa o ConnectorInterface
e permite que você se conecte aos caminhos de soquete do UNIX Domain (UDS) como este:
$ connector = new React Socket UnixConnector ();
$ connector -> connect ( ' /tmp/demo.sock ' )-> then ( function ( React Socket ConnectionInterface $ connection ) {
$ connection -> write ( " HELLO n" );
});
Conectando -se aos soquetes de domínio UNIX é uma operação atômica, ou seja, sua promessa se estabelecerá (resolverá ou rejeitará) imediatamente. Como tal, chamando cancel()
na promessa resultante não tem efeito.
O método
getRemoteAddress()
retornará o caminho do soquete de domínio UNIX de destino (UDS), conforme fornecido ao métodoconnect()
, antecedido ao Schemeunix://
, por exemplo,unix:///tmp/demo.sock
. O métodogetLocalAddress()
provavelmente retornará um valornull
, pois esse valor não é aplicável às conexões UDS aqui.
Esta classe leva um parâmetro opcional LoopInterface|null $loop
que pode ser usado para passar na instância do loop de evento para usar para este objeto. Você pode usar um valor null
aqui para usar o loop padrão. Esse valor não deve ser fornecido, a menos que você tenha certeza de que deseja usar explicitamente uma determinada instância de loop de evento.
A classe FixedUriConnector
implementa o ConnectorInterface
e decora um conector existente para sempre usar um URI fixo pré -configurado.
Isso pode ser útil para os consumidores que não suportam certos URIs, como quando você deseja se conectar explicitamente a um caminho de soquete de domínio UNIX (UDS), em vez de se conectar a um endereço padrão assumido por uma API de nível 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 ' );
A forma recomendada de instalar esta biblioteca é através do Composer. Novo no Compositor?
Uma vez lançado, este projeto seguirá o SemVer. No momento, isso instalará a versão de desenvolvimento mais recente:
composer require react/socket:^3@dev
Consulte também o CHANGELOG para obter detalhes sobre atualizações de versão.
Este projeto visa rodar em qualquer plataforma e, portanto, não requer nenhuma extensão PHP e suporta execução em PHP 7.1 até o atual PHP 8+. É altamente recomendável usar a versão mais recente do PHP suportada para este projeto.
PHP legado <7.3.3 (e PHP <7.2.15) sofre de um bug em que Feof () pode bloquear com 100% de uso da CPU em registros de TLS fragmentados. Tentamos contornar isso sempre consumindo o buffer de recebimento completo de uma só vez para evitar dados obsoletos em buffers TLS. Sabe-se que isso contorna em torno do alto uso da CPU para pares de bem-estar, mas isso pode causar pedaços de dados muito grandes para cenários de alto rendimento. O comportamento de buggy ainda pode ser acionado devido a buffers de E/S de rede ou colegas maliciosos nas versões afetadas, é altamente recomendável atualização.
O Legacy PHP <7.1.4 sofre de um bug ao escrever grandes pedaços de dados sobre os fluxos de TLS de uma só vez. Tentamos contornar isso, limitando o tamanho da gravação a 8192 bytes apenas para versões PHP mais antigas. Isso é apenas uma subida e tem uma penalidade perceptível de desempenho nas versões afetadas.
Para executar o conjunto de testes, primeiro você precisa clonar este repositório e depois instalar todas as dependências através do Composer:
composer install
Para executar o conjunto de testes, vá até a raiz do projeto e execute:
vendor/bin/phpunit
O conjunto de testes também contém vários testes de integração funcionais que dependem de uma conexão estável à Internet. Se você não quiser executá -los, eles podem simplesmente ser ignorados assim:
vendor/bin/phpunit --exclude-group internet
MIT, consulte o arquivo LICENSE.