Motivi per cui la connessione del client è fallita

Quando la connessione fallisce, il client di solito presenta due tipi di errori: connection refuse e connection timeout.

connection refuse (connessione rifiutata)

Di solito le ragioni sono le seguenti:

  1. La porta a cui il client si connette è errata.
  2. Il nome di dominio o l'IP a cui il client si connette è errato.
  3. Se il client utilizza un nome di dominio per connettersi, il nome di dominio potrebbe puntare a un IP del server errato.
  4. Il server utilizza un CDN o un proxy di accelerazione, causando un'inesattezza tra l'IP reale con cui ci si collega e l'IP previsto.
  5. Il server non è stato avviato oppure la porta non è in ascolto.
  6. È stato utilizzato un software di proxy di rete.
  7. L’IP in ascolto sul server e l’indirizzo di accesso non si trovano nello stesso segmento. Ad esempio, se il server ascolta su 127.0.0.1, il client può connettersi solo tramite 127.0.0.1 e non tramite l'IP della rete locale o l'IP pubblico. Si consiglia di impostare l'indirizzo di ascolto su 0.0.0.0, in modo che localmente, nella rete interna e online, sia possibile connettersi.

connection timeout (timeout di connessione)

Di solito le ragioni sono le seguenti:

  1. Il firewall del server impedisce la connessione; si può provare a disattivare temporaneamente il firewall.
  2. Se si tratta di un server cloud, il gruppo di sicurezza potrebbe anche impedire l’instaurazione della connessione, è necessario aprire la porta corrispondente dal pannello di gestione.
  3. Se si utilizza un pannello come 宝塔, è necessario aprire la porta corrispondente in 宝塔.
  4. Il server non esiste o non è stato avviato.
  5. Se il client utilizza un nome di dominio per connettersi, il nome di dominio potrebbe puntare a un IP del server errato.
  6. L'IP a cui accede il client è l'IP interno del server e il client e il server non si trovano nella stessa rete locale.

cannot assign requested address (impossibile assegnare l'indirizzo richiesto)

In qualità di client, per ogni connessione avviata è necessario occupare una porta temporanea locale. Un server ha di solito una gamma di porte temporanee disponibili di circa 20-30 mila. Se il numero di connessioni a un server specifico supera questo valore, non si potranno più assegnare porte disponibili, generando questo errore.
Si può aumentare il numero di porte temporanee locali modificando il parametro del kernel in /etc/sysctl.conf per net.ipv4.ip_local_port_range, ad esempio impostandolo su 10000 65535 (che aumenta il numero delle porte locali a 55535). Per rendere effettive le modifiche, eseguire sysctl -p.
Inoltre, dopo che una connessione è stata chiusa, potrebbe rimanere in stato TIME_WAIT, continuando a occupare la porta locale corrispondente per un certo periodo. Ciò significa che se si avviano un gran numero di connessioni brevi (superiori a 20-30 mila) in breve tempo si può ricevere l’errore Cannot assign requested address. In questo caso, può essere utile impostare il kernel per un rapido recupero delle porte TIME_WAIT, fare riferimento a ottimizzazione del kernel.

Attenzione
La limitazione del numero di porte locali si applica solo ai client; il server non ha limitazioni sul numero di porte locali, quindi, a condizione che ci siano abbastanza risorse, il numero di connessioni mantenute dal server può essere considerato illimitato.

Altri errori

Se si verifica un errore diverso da connection refuse e connection timeout, le cause sono generalmente le seguenti:

1. Il protocollo di comunicazione utilizzato dal client non è coerente con quello del server.
Ad esempio, se il server utilizza il protocollo di comunicazione HTTP, un client che utilizza il protocollo di comunicazione WebSocket non potrà connettersi. Se il client si connette utilizzando il protocollo WebSocket, anche il server deve utilizzare il protocollo WebSocket. Se il server è un servizio HTTP, allora il client deve accedervi utilizzando il protocollo HTTP.

Il principio qui è simile a comunicare con un britannico; è necessario utilizzare l'inglese. Per comunicare con un giapponese, è necessario utilizzare il giapponese. Qui la lingua è simile a un protocollo di comunicazione: ambedue le parti (client e server) devono utilizzare lo stesso linguaggio per comunicare, altrimenti non sarà possibile comunicare.

Esempi comuni di errori dovuti a protocolli di comunicazione non coerenti:

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

Soluzione:
Dai due errori di cui sopra, si può notare che il client utilizza una connessione ws, quindi il server deve anch'esso essere configurato per utilizzare il protocollo WebSocket. Parte del codice di ascolto del server deve specificare il protocollo WebSocket per poter comunicare, come riportato di seguito.

Se si tratta di GatewayWorker, il codice di ascolto sarà simile a:

// protocollo websocket, in questo modo il client può connettersi usando ws://... . xxxx è la porta, che non deve essere modificata
$gateway = new Gateway('websocket://0.0.0.0:xxxx');

Se si tratta di Workerman, sarà:

// protocollo websocket, in questo modo il client può connettersi usando ws://... . xxxx è la porta, che non deve essere modificata
$worker = new Worker('websocket://0.0.0.0:xxxx');