İstemci Bağlantı Başarısızlık Nedenleri
Bağlantı başarısızlığı yaşayan istemciler genellikle iki hata mesajı alır: connection refuse ve connection timeout.
connection refuse (Bağlantı Reddedildi)
Genellikle şu nedenlerden kaynaklanır:
- İstemcinin bağlanmaya çalıştığı port yanlıştır.
- İstemcinin bağlanmaya çalıştığı alan adı veya IP yanlıştır.
- Eğer istemci alan adı kullanarak bağlanıyorsa, alan adı muhtemelen yanlış sunucu IP'sine işaret ediyor.
- Sunucu, bağlantının gerçekteki IP'si ile beklenen IP'si arasında fark yaratan bir CDN veya hızlandırma proxy'si kullanıyor.
- Sunucu başlatılmamış veya port dinlenmiyor.
- Ağ proxy yazılımı kullanılıyor.
- Sunucunun dinlediği IP ile erişim adresi aynı IP bloğunda değil. Örneğin, sunucu 127.0.0.1 üzerinde dinliyorsa, istemci yalnızca 127.0.0.1 üzerinden bağlanabilir, yerel ağ IP'si veya dış ağ IP'si üzerinden bağlanamaz. Dinleme adresinin 0.0.0.0 olarak ayarlanması önerilir; böylece yerel, iç ve dış ağdan bağlantı alınabilir.
connection timeout (Bağlantı Zaman Aşımı)
Genellikle şu nedenlerden kaynaklanır:
- Sunucu güvenlik duvarı bağlantıyı engelliyor, geçici olarak güvenlik duvarını kapatmayı deneyin.
- Eğer bir bulut sunucusu ise, güvenlik grubu da bağlantı kurulmasını engelleyebilir, yönetim panelinde ilgili portu açmanız gerekebilir.
- Eğer Baota gibi bir panel kullanıyorsanız, ilgili portu Baota'da açmanız gerekebilir.
- Sunucu mevcut değil veya başlatılmamış.
- Eğer istemci alan adı kullanarak bağlanıyorsa, alan adı muhtemelen yanlış sunucu IP'sine işaret ediyor.
- İstemcinin eriştiği IP, sunucunun iç ağ IP'sidir ve istemci ile sunucu aynı yerel ağda değildir.
cannot assign requested address (İstenen adres atanamıyor)
İstemci olarak, her bağlantı başlattığınızda yerel bir geçici port tahsis edilmesi gerekir; bir sunucuda varsayılan olarak yaklaşık 20-30 bin geçici port kullanılabilir. Özel bir sunucuya başlatılan bağlantı sayısı bu değeri aşarsa, kullanılabilir bir port atanamaz ve bu hata oluşur.
Yerel geçici port sayısını artırmak için net.ipv4.ip_local_port_range parametresini değiştirerek /etc/sysctl.conf dosyasını güncelleyebilirsiniz, örneğin 10000 65535 olarak ayarlamak (yerel port aralığı 10000 ile 65535 arasına ayarlandığında, yerel port sayısı 55535'e yükselebilir) ve ardından sysctl -p komutunu çalıştırmalısınız.
Ayrıca bağlantı kesildikten sonra bağlantı TIME_WAIT durumuna geçer, bu da ilgili yerel portun bir süre boyunca kullanılmaya devam edeceği anlamına gelir; yani kısa bir süre içinde çok sayıda (20-30 binin üzerinde) kısa bağlantı başlatmanız durumunda da Cannot assign requested address hatası alınacaktır. Eğer böyle bir durumdaysanız, TIME_WAIT'in hızlı bir şekilde geri alınmasını sağlamak için çekirdek ayarlarını yapılandırarak çözebilirsiniz; çekirdek optimizasyonu kısmına bakabilirsiniz.
Not
Yerel port sayısı sınırlaması yalnızca istemci içindir, sunucunun yerel port sınırlaması yoktur; yeterli kaynak varsa, sunucu bağlantı sayısını sınırsız olarak sürdürebilir.
Diğer Hatalar
Eğer meydana gelen hata connection refuse veya connection timeout değilse, genellikle şu nedenlerden kaynaklanır:
1. İstemcinin kullandığı iletişim protokolü ile sunucu arasında bir uyumsuzluk vardır.
Örneğin, sunucu http iletişim protokolünü kullanıyorsa, istemci websocket iletişim protokolüyle bağlanamaz. Eğer istemci websocket protokolü kullanıyorsa, sunucunun da websocket protokolü kullanması gerekir. Sunucu http protokolüne sahipse, istemcinin http protokolü ile erişmesi gerekmektedir.
Buradaki prensip, bir İngilizle iletişim kurmak istiyorsanız İngilizce kullanmanız gerektiği gibidir. Eğer bir Japonla iletişim kurmak istiyorsanız, Japonca kullanmanız gerekir. Burada dil, iletişim protokolüne benzer; her iki tarafın (istemci ve sunucu) aynı dili kullanması gerekmektedir; aksi takdirde iletişim mümkün olmaz.
İletişim protokolü uyumsuzluğuna bağlı yaygın hata mesajları şunlardır:
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
Çözüm Yolu:
Yukarıdaki iki hatadan, istemcinin ws bağlantısını websocket protokolü ile kullandığı anlaşılıyor. Sunucunun da websocket protokolü kullanıyor olması gerekiyor. Sunucunun dinleme kodunun ilgili websocket protokolünü belirtmesi gerekmektedir; örneğin aşağıdaki gibi:
Eğer bir gatewayWorker ise, dinleme kısmındaki kod şu şekilde olmalıdır:
// websocket protokolü, böylece istemci ws://... ile bağlanabilir. xxxx portu değiştirilmemelidir
$gateway = new Gateway('websocket://0.0.0.0:xxxx');
Eğer Workerman ise:
// websocket protokolü, böylece istemci ws://... ile bağlanabilir. xxxx portu değiştirilmemelidir
$worker = new Worker('websocket://0.0.0.0:xxxx');