Motivos para Falha na Conexão do Cliente

Quando a conexão falha, o cliente geralmente apresentará dois tipos de erros: connection refuse e connection timeout.

connection refuse (conexão recusada)

Geralmente, as razões são as seguintes:

  1. A porta para a qual o cliente está tentando se conectar está errada.
  2. O domínio ou IP que o cliente está tentando acessar está incorreto.
  3. Se o cliente usou um domínio para se conectar, o domínio pode estar apontando para um IP de servidor incorreto.
  4. O servidor está usando um CDN ou outro proxy de aceleração, o que faz com que o IP real da conexão não corresponda ao IP esperado.
  5. O servidor não está em execução ou a porta não está sendo monitorada.
  6. Um software de proxy de rede está sendo usado.
  7. O IP que o servidor está monitorando e o endereço de acesso não estão na mesma faixa de endereço. Por exemplo, se o servidor estiver monitorando 127.0.0.1, o cliente só poderá se conectar através de 127.0.0.1, não poderá se conectar através de IP da rede local ou IP externo. Recomenda-se configurar o endereço de escuta como 0.0.0.0, assim a conexão poderá ser feita tanto localmente quanto na rede interna ou externa.

connection timeout (tempo de conexão excedido)

Geralmente, as razões são as seguintes:

  1. O firewall do servidor está bloqueando a conexão; tente desativar temporariamente o firewall.
  2. Se for um servidor em nuvem, o grupo de segurança também pode estar bloqueando a conexão, sendo necessário abrir a porta correspondente no painel de gerenciamento.
  3. Se um painel como o Baota estiver em uso, será necessário abrir a porta correspondente nele.
  4. O servidor não existe ou não está em funcionamento.
  5. Se o cliente usou um domínio para se conectar, o domínio pode estar apontando para um IP de servidor incorreto.
  6. O IP que o cliente está tentando acessar é um IP interno do servidor, e o cliente e o servidor não estão na mesma rede local.

cannot assign requested address (não é possível atribuir o endereço solicitado)

Como cliente, a cada conexão iniciada, é necessário ocupar uma porta temporária local; uma única máquina pode ter cerca de 20.000 a 30.000 portas temporárias disponíveis por padrão. Se o número de conexões iniciadas para um servidor específico exceder esse valor, não será possível atribuir uma porta disponível, resultando nesse erro.
É possível aumentar o número de portas temporárias locais alterando o parâmetro do núcleo em /etc/sysctl.conf, configurando net.ipv4.ip_local_port_range, por exemplo, definindo como 10000 65535 (a faixa de portas locais é ajustada para 10000 a 65535, aumentando assim o número de portas locais para 55.535), e executando sysctl -p para aplicar as alterações.
Além disso, após a conexão ser encerrada, ela entra no estado TIME_WAIT e ainda ocupará a porta local correspondente por um período, ou seja, iniciar um grande número de conexões curtas (mais de 20.000 a 30.000) em um curto período também resultará em Cannot assign requested address. Se este for o caso, é possível resolver ajustando o núcleo para recuperar rapidamente o TIME_WAIT; consulte otimização do núcleo.

Atenção
A limitação do número de portas locais se aplica apenas ao cliente; o servidor não tem essa limitação, desde que haja recursos suficientes, o número de conexões do servidor pode ser considerado ilimitado.

Outros erros

Se o erro que ocorreu não for connection refuse ou connection timeout, então geralmente as razões são as seguintes:

1. O protocolo de comunicação usado pelo cliente é diferente do protocolo do servidor.
Por exemplo, se o servidor estiver usando o protocolo http, o cliente não poderá se conectar usando o protocolo websocket. Se o cliente usar o protocolo websocket, o servidor também precisa ser compatível com o protocolo websocket. Se o servidor for um serviço http, o cliente deve acessá-lo usando o protocolo http.

Aqui, o princípio é semelhante a se você quiser se comunicar com um britânico; você deve usar inglês. Se você quiser se comunicar com um japonês, deverá usar japonês. Aqui, a linguagem se assemelha ao protocolo de comunicação; ambas as partes (cliente e servidor) devem usar a mesma linguagem para se comunicarem, caso contrário, a comunicação falhará.

Erros comuns devido à incompatibilidade de protocolo de comunicação incluem:

WebSocket connection to 'ws://xxx.com:xx/' failed: Error during WebSocket handshake: Unexpected response code: xxx

WebSocket connection to 'ws://xxx.com:xx/' failed: Error during WebSocket handshake: net::ERR_INVALID_HTTP_RESPONSE

Solução:
Com base nas duas mensagens de erro acima, é evidente que o cliente está usando a conexão ws, que é um protocolo websocket. O servidor também precisa ser configurado para o protocolo websocket para que funcione. O código de parte de escuta do servidor deve especificar o protocolo websocket para permitir a comunicação, como mostrado abaixo.

Se for um gatewayWorker, o código de parte de escuta se parecerá com:

// protocolo websocket, assim o cliente pode se conectar usando ws://... O xxxx é a porta que não precisa ser alterada
$gateway = new Gateway('websocket://0.0.0.0:xxxx');

Se for Workerman, será:

// protocolo websocket, assim o cliente pode se conectar usando ws://... O xxxx é a porta que não precisa ser alterada
$worker = new Worker('websocket://0.0.0.0:xxxx');