Canlı sohbet, anlık bildirimler, borsa ekranlarındaki saniyelik fiyat değişimleri, çok kişinin aynı anda düzenlediği belgeler, sipariş takip haritaları... Bugün kullandığımız uygulamaların giderek büyüyen bir kısmı "gerçek zamanlı" çalışıyor. Bunların hepsinin altında, kullanıcının sayfayı yenilemesine gerek kalmadan veriyi anında ileten bir teknoloji yatıyor. Çoğu zaman bu teknolojinin adı WebSocket.
Bu rehberde WebSocket'in ne olduğunu, klasik HTTP'den nasıl ayrıldığını, ne zaman tercih edilmesi gerektiğini ve gerçek bir uygulamanın nasıl kurulacağını adım adım ele alıyoruz. İstanbul merkezli bir yazılım ajansı olarak gerçek zamanlı sohbet, canlı takip ve bildirim sistemleri geliştirirken edindiğimiz pratik deneyimleri; örnek kod parçaları, ölçeklenebilirlik ve güvenlik notlarıyla birlikte paylaşıyoruz.
WebSocket nedir ve neden ortaya çıktı?
WebSocket, bir istemci (genellikle tarayıcı) ile sunucu arasında çift yönlü ve sürekli açık bir bağlantı kuran bir iletişim protokolüdür. Bağlantı bir kez kurulduğunda, hem istemci hem sunucu birbirine istedikleri zaman, yeni bir istek beklemeden mesaj gönderebilir. Bu, "tam çift yönlü" (full-duplex) iletişim demektir.
Bunu anlamak için klasik web modelini hatırlamak gerekir. Geleneksel HTTP'de iletişim tek yönlüdür ve istek-yanıt mantığıyla çalışır: tarayıcı bir istek gönderir, sunucu yanıt verir ve bağlantı kapanır. Sunucu, tarayıcıya kendiliğinden bir şey gönderemez. Yeni bir veri olduğunda kullanıcıyı haberdar etmenin tek yolu, tarayıcının tekrar tekrar "yeni bir şey var mı?" diye sormasıdır.
Gerçek zamanlı bir deneyim için bu model yetersizdir. Bir sohbet uygulamasında, karşı taraf mesaj yazdığında bunu anında görmek istersiniz; sunucunun size mesaj "itebilmesi" gerekir. WebSocket tam olarak bu ihtiyacı karşılamak için tasarlandı ve bugün tüm modern tarayıcılar tarafından desteklenir.
WebSocket, HTTP polling ve SSE arasındaki fark
WebSocket'e geçmeden önce, gerçek zamanlılığı taklit etmek için kullanılan eski yöntemleri ve alternatifleri bilmek faydalı. Çünkü her senaryo için WebSocket en doğru seçim olmayabilir.
- Short polling: Tarayıcı belirli aralıklarla (örneğin her 3 saniyede bir) sunucuya "yeni veri var mı?" diye sorar. Basittir ama gecikmelidir ve gereksiz çok sayıda istek üretir.
- Long polling: Tarayıcı istek gönderir, sunucu yeni veri olana kadar yanıtı bekletir. Polling'den daha verimlidir ama yine de her mesajdan sonra bağlantının yeniden kurulması gerekir.
- Server-Sent Events (SSE): Sunucudan istemciye tek yönlü, sürekli bir veri akışı sağlar. Borsa fiyatları ya da canlı skor gibi yalnızca sunucudan akan verilerde idealdir, ama istemciden sunucuya anlık veri gönderimi gerektirmez.
- WebSocket: Çift yönlü, düşük gecikmeli, kalıcı bağlantı. Sohbet, çok oyunculu oyunlar, ortak düzenleme gibi iki yönlü etkileşim gereken her yerde en uygun seçenektir.
Aşağıdaki tablo, hangi senaryoda hangi yaklaşımın daha uygun olduğunu özetliyor:
| Özellik | Short Polling | Long Polling | SSE | WebSocket |
|---|---|---|---|---|
| Yön | İstek-yanıt | İstek-yanıt | Tek yön (sunucu) | Çift yön |
| Gecikme | Yüksek | Orta | Düşük | Çok düşük |
| Sunucu yükü | Yüksek | Orta | Düşük | Düşük |
| Tarayıcı desteği | Tam | Tam | Geniş | Tam |
| İdeal kullanım | Basit durum kontrolü | Bildirim | Canlı akış | Sohbet, oyun, iş birliği |
Pratik kural: Veri yalnızca sunucudan istemciye akıyorsa SSE genellikle daha basit ve yeterlidir. İki yönlü, sık ve düşük gecikmeli etkileşim gerekiyorsa WebSocket'e yönelin.
WebSocket el sıkışması nasıl çalışır?
WebSocket bağlantısı aslında bir HTTP isteğiyle başlar. İstemci, sunucuya özel bir başlık (Upgrade: websocket) içeren bir istek gönderir ve "bu bağlantıyı WebSocket'e yükseltelim" der. Sunucu kabul ederse, HTTP 101 (Switching Protocols) yanıtını döner ve aynı TCP bağlantısı artık WebSocket protokolüyle çalışmaya başlar.
Bu "yükseltme" (upgrade) mekanizması zekice tasarlanmıştır: WebSocket trafiği 80 (ws) ve 443 (wss) portları üzerinden gittiği için mevcut web altyapısı, güvenlik duvarları ve proxy'lerle uyumlu çalışır. Bağlantı kurulduktan sonra veri, küçük "frame" denen paketler halinde iki yönde de akar; her mesaj için yeni bir HTTP başlığı eklenmediğinden ağ yükü çok düşüktür.
Bağlantı URL'leri iki şema kullanır: şifrelenmemiş bağlantılar için ws:// ve TLS ile şifrelenmiş güvenli bağlantılar için wss://. Üretim ortamında istisnasız wss:// kullanılmalıdır.
Node.js ile basit bir WebSocket sunucusu
Teoriyi pratiğe dökelim. Node.js ortamında ws kütüphanesiyle birkaç satırda çalışan bir WebSocket sunucusu kurabilirsiniz. Aşağıdaki örnek, bağlanan her istemciyi karşılayan ve gelen her mesajı tüm bağlı istemcilere ileten basit bir yayın (broadcast) sunucusudur:
const { WebSocketServer } = require('ws');
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', (socket) => {
console.log('Yeni istemci bağlandi');
socket.send(JSON.stringify({ tip: 'sistem', mesaj: 'Sohbete hos geldiniz' }));
socket.on('message', (veri) => {
const gelen = JSON.parse(veri);
// Mesaji tum bagli istemcilere ilet
wss.clients.forEach((istemci) => {
if (istemci.readyState === istemci.OPEN) {
istemci.send(JSON.stringify({ tip: 'mesaj', icerik: gelen.icerik }));
}
});
});
socket.on('close', () => {
console.log('Istemci ayrildi');
});
});
Bu kadarı, yerel bir sohbet odasının temel motorunu oluşturur. Gerçek bir projede mesajları doğrulamak, kimlik denetimi eklemek ve hata yönetimi yapmak gerekir; ama çekirdek mantık tam olarak budur: bağlan, dinle, ilet.
Tarayıcı tarafında WebSocket istemcisi
Sunucu hazır olduğunda, tarayıcı tarafı bağlantıyı kurmak oldukça basittir. Modern tarayıcılar yerleşik bir WebSocket nesnesiyle gelir, ek bir kütüphaneye gerek yoktur:
const baglanti = new WebSocket('wss://ornek-sunucu.com');
baglanti.onopen = () => {
console.log('Baglanti acildi');
baglanti.send(JSON.stringify({ icerik: 'Merhaba dunya' }));
};
baglanti.onmessage = (olay) => {
const veri = JSON.parse(olay.data);
console.log('Yeni mesaj:', veri.icerik);
};
baglanti.onclose = () => {
console.log('Baglanti kapandi, yeniden baglaniliyor...');
// Burada yeniden baglanma mantigi calistirilir
};
baglanti.onerror = (hata) => {
console.error('Baglanti hatasi:', hata);
};
Dikkat edilmesi gereken kritik nokta, onclose içindeki yeniden bağlanma mantığıdır. Mobil ağlarda ve dengesiz bağlantılarda WebSocket kopabilir; sağlam bir istemci, bağlantı koptuğunda artan aralıklarla (exponential backoff) yeniden bağlanmayı denemelidir. Bu detay, kullanıcı deneyiminin sessiz kahramanıdır.
Gerçek zamanlı sohbet uygulaması mimarisi
Tek sunuculu basit örnekler öğreticidir ama gerçek bir ürün daha fazla katman gerektirir. Üretime hazır bir sohbet uygulamasında tipik olarak şu bileşenler bulunur:
- Kimlik doğrulama katmanı: Bağlantı kurulurken kullanıcının kim olduğu, genellikle bir token (örneğin JWT) ile doğrulanır.
- Oda ve kanal yönetimi: Kullanıcılar farklı sohbet odalarına ayrılır; mesajlar yalnızca ilgili odadaki kişilere gider.
- Mesaj kalıcılığı: Mesajlar bir veritabanına yazılır ki kullanıcı sonradan geçmişi görebilsin.
- Durum yönetimi: Kimin çevrimiçi olduğu, "yazıyor..." göstergeleri, okundu bilgisi.
- Ölçekleme katmanı: Birden fazla sunucu örneği arasında mesaj senkronizasyonu.
Bu mimaride WebSocket yalnızca taşıma katmanıdır; asıl iş mantığı, oda yönetimi ve kalıcılık etrafında kurulur. İyi tasarlanmış bir sistemde mesajın akışı şöyledir: istemci mesajı gönderir, sunucu doğrular ve veritabanına yazar, ardından ilgili odadaki tüm bağlı istemcilere iletir. Bu sistemleri mevcut altyapınıza bağlamak için sıklıkla API entegrasyonu hizmetlerimizden yararlanan ekiplerle çalışıyoruz.
Ölçeklenebilirlik: tek sunucudan binlerce kullanıcıya
WebSocket'in en sık göz ardı edilen yönü ölçeklenmesidir. HTTP'de her istek bağımsızdır, dolayısıyla istekleri farklı sunuculara dağıtmak kolaydır. Oysa WebSocket'te bağlantı kalıcıdır; bir kullanıcı belirli bir sunucu örneğine bağlanır ve bağlantı süresince orada kalır. Peki iki kullanıcı farklı sunuculara bağlıysa, biri mesaj gönderdiğinde diğeri bunu nasıl alacak?
Çözüm, sunucular arası bir mesajlaşma katmanıdır. En yaygın yaklaşım Redis Pub/Sub kullanmaktır: her sunucu, Redis üzerinden bir kanala abone olur. Bir sunucuya mesaj geldiğinde onu Redis'e yayınlar; diğer tüm sunucular bu mesajı alır ve kendi bağlı istemcilerine iletir. Böylece bağlantılar farklı sunuculara dağılsa bile mesajlar herkese ulaşır.
Ölçeklenebilir bir WebSocket mimarisinde dikkat edilecek başlıklar:
- Yatay ölçekleme: Yük dengeleyici (load balancer) "sticky session" desteklemeli; bir kullanıcının tüm istekleri aynı sunucuya gitmelidir.
- Mesaj veriyolu: Redis Pub/Sub veya Kafka gibi bir katman, sunucular arası senkronizasyonu sağlar.
- Bağlantı limitleri: Tek bir Node.js süreci on binlerce eşzamanlı bağlantıyı taşıyabilir, ama bellek ve dosya tanımlayıcı (file descriptor) limitleri ayarlanmalıdır.
- Yatay otomatik ölçekleme: Yük arttığında yeni sunucu örneklerinin otomatik devreye girmesi.
Türkiye'de canlı yayın, e-spor ve anlık açık artırma platformları gibi ani yük artışları yaşayan projelerde bu mimari kararlar, sistemin saniyede on binlerce mesajı taşıyıp taşıyamayacağını belirler. Ölçeklenebilirliği baştan tasarlamak, sonradan yeniden yazmaktan çok daha ucuzdur.
Güvenlik: gerçek zamanlı sistemlerin kırılgan noktaları
Sürekli açık bağlantılar, geleneksel HTTP'den farklı güvenlik riskleri taşır. WebSocket bağlantısı bir kez kurulduğunda kalıcı olduğundan, kimlik doğrulama ve yetkilendirme her mesaj için değil, bağlantı kurulurken ve kanal bazında dikkatle yönetilmelidir.
Üretim ortamında uygulanması gereken güvenlik önlemleri:
- Her zaman wss:// kullanın: Şifrelenmemiş ws:// bağlantıları, araya girme (man-in-the-middle) saldırılarına açıktır.
- Bağlantıda kimlik doğrulama: El sıkışma sırasında token doğrulayın; geçersiz tokenlı bağlantıları reddedin.
- Origin kontrolü: Cross-Site WebSocket Hijacking saldırılarına karşı Origin başlığını doğrulayın.
- Mesaj boyutu ve hız sınırı: Tek bir istemcinin dakikada gönderebileceği mesaj sayısını ve mesaj boyutunu sınırlayın (rate limiting). Aksi halde bir kullanıcı sistemi mesaj seli ile boğabilir.
- Girdi doğrulama: Gelen her mesajı, sunucuya gelen herhangi bir API isteği gibi titizlikle doğrulayın.
Güvenlik, gerçek zamanlı sistemlerde sonradan eklenen bir katman değil, mimarinin temel bir parçası olmalıdır. Özellikle finansal veri, kişisel mesaj veya KVKK kapsamındaki bilgilerin aktığı sistemlerde bu önlemler pazarlık konusu değildir.
Ham WebSocket mi, Socket.IO mu?
Geliştirme ekiplerinin sık sorduğu sorulardan biri, doğrudan WebSocket mi yoksa Socket.IO gibi bir kütüphane mi kullanılmalı. İkisinin de yeri var.
Ham WebSocket en hafif ve standart çözümdür. Tarayıcıda yerleşiktir, ek bağımlılık gerektirmez, performansı en yüksektir. Ancak yeniden bağlanma, oda yönetimi, eski tarayıcılar için yedek mekanizma gibi özellikleri kendiniz yazmanız gerekir.
Socket.IO ise bunların çoğunu hazır sunar: otomatik yeniden bağlanma, oda ve namespace yönetimi, WebSocket desteklenmeyen ortamlarda otomatik olarak long polling'e düşme, mesaj onayı (acknowledgement) gibi özellikler kutudan çıkar. Bunun karşılığında ek bir kütüphane yükü ve kendi protokol katmanı gelir; Socket.IO istemcisi yalnızca Socket.IO sunucusuyla konuşur.
Pratik öneri: Hızlı geliştirilmesi gereken, çok sayıda oda ve bağlantı yönetimi içeren tipik iş uygulamalarında Socket.IO zaman kazandırır. Maksimum performans, tam kontrol ve standartlara bağlılık gereken sistemlerde ham WebSocket daha doğru seçimdir. Karar, projenin ölçeğine ve ekibin önceliğine bağlıdır.
Mobil uygulamalarda gerçek zamanlı veri ve bildirimler
Gerçek zamanlılık yalnızca web'e özgü değildir. Mobil uygulamalarda da sohbet, canlı takip ve anlık bildirim ihtiyacı yaygındır; ancak mobilin kendine özgü zorlukları vardır. Telefon arka plana alındığında ya da ağ değiştiğinde (Wi-Fi'den mobil veriye geçiş) WebSocket bağlantısı sık sık kopar.
Mobilde tipik yaklaşım, iki mekanizmayı birleştirmektir:
- Uygulama açık ve önplandayken: WebSocket ile düşük gecikmeli, çift yönlü iletişim kullanılır. Canlı sohbet ve "yazıyor..." göstergeleri için idealdir.
- Uygulama arka plandayken veya kapalıyken: İşletim sistemi, açık WebSocket bağlantılarını askıya alır. Bu durumda kullanıcıyı uyandırmak için push notification servisleri (Android'de FCM, iOS'ta APNs) devreye girer.
Bu hibrit model, hem anlık deneyimi hem pil verimliliğini korur. React Native gibi çapraz platform çözümlerle bu yapıları tek kod tabanıyla kurmak mümkündür; mobil tarafın detaylarını mobil uygulama geliştirme hizmetlerimiz kapsamında ele alıyoruz. Gerçek zamanlı veri akışı, modern bir SaaS ürününün de ayrılmaz parçasıdır; bu mimariyi bir ürünün içine nasıl yerleştireceğinizi SaaS geliştirme rehberi yazımızda daha geniş ele aldık.
Performans ipuçları ve sık yapılan hatalar
WebSocket projelerinde tekrar tekrar karşılaştığımız sorunlar ve çözümleri:
- Yeniden bağlanma mantığının olmaması: Bağlantı koptuğunda sessizce ölen uygulamalar en sık görülen hatadır. Mutlaka artan aralıklı yeniden bağlanma ekleyin.
- Heartbeat (kalp atışı) eksikliği: Bağlantının canlı olup olmadığını periyodik ping/pong mesajlarıyla kontrol edin; "yarı açık" bağlantıları tespit edip kapatın.
- Her şeyi WebSocket'ten geçirmek: Tek seferlik istekler için normal HTTP daha uygundur. WebSocket'i yalnızca gerçek zamanlılık gereken yerde kullanın.
- Mesaj boyutunu kontrol etmemek: Büyük dosyaları WebSocket üzerinden göndermek bağlantıyı tıkar; büyük veriler için ayrı bir HTTP yükleme kanalı kullanın.
- Ölçeklemeyi sona bırakmak: Tek sunucuda çalışan bir prototipi, mimari değiştirmeden üretime almak, kullanıcı sayısı arttığında çökmelere yol açar.
Bu hataların çoğu, projenin başında doğru mimari kararlarla kolayca önlenir; sonradan düzeltmek ise hem maliyetli hem risklidir.
Sıkça Sorulan Sorular
WebSocket her gerçek zamanlı uygulama için gerekli mi?
Hayır. Eğer veri yalnızca sunucudan istemciye akıyorsa (canlı skor, borsa fiyatı, bildirim akışı gibi) ve istemciden anlık veri gönderimi gerekmiyorsa, Server-Sent Events çoğu zaman daha basit ve yeterlidir. WebSocket asıl gücünü, sohbet, çok oyunculu oyun veya ortak belge düzenleme gibi çift yönlü ve sık etkileşim gerektiren senaryolarda gösterir. Doğru araç, gereksinime göre seçilmelidir.
Tek bir sunucu kaç eşzamanlı WebSocket bağlantısını taşıyabilir?
Doğru yapılandırılmış tek bir Node.js süreci, donanıma ve mesaj yoğunluğuna bağlı olarak on binlerce, bazı durumlarda yüz binlere yakın eşzamanlı bağlantıyı taşıyabilir. Ancak gerçek sınır, mesaj trafiğinin yoğunluğu ve işletim sistemi limitleridir (dosya tanımlayıcı sayısı, bellek). Yüksek kullanıcı sayısı bekleniyorsa, baştan yatay ölçeklenebilir bir mimari kurmak gerekir.
WebSocket bağlantısı koparsa veriler kaybolur mu?
Bağlantı koptuğunda iletilmekte olan mesajlar kaybolabilir; bu yüzden mesajları sunucu tarafında bir veritabanına kalıcı olarak yazmak önemlidir. Sağlam sistemlerde istemci yeniden bağlandığında, bağlantının koptuğu andan sonraki mesajları sunucudan tekrar ister. Böylece kullanıcı, çevrimdışıyken kaçırdığı mesajları geri bağlandığında görür. Kalıcılık olmadan gerçek zamanlılık tek başına yeterli değildir.
WebSocket güvenli midir?
WebSocket, doğru yapılandırıldığında güvenlidir. wss:// ile TLS şifrelemesi kullanmak, bağlantıda kimlik doğrulamak, Origin başlığını kontrol etmek ve hız sınırlaması uygulamak temel önlemlerdir. Güvenlik açıkları genellikle protokolün kendisinden değil, eksik yapılandırmadan kaynaklanır. Kişisel ve finansal verinin aktığı sistemlerde bu önlemler zorunludur.
Mevcut HTTP API'mle WebSocket'i birlikte kullanabilir miyim?
Evet, hatta önerilen yaklaşım budur. Çoğu uygulama, geleneksel işlemler (giriş, veri kaydetme, dosya yükleme) için REST API'sini kullanmaya devam ederken yalnızca gerçek zamanlı parçaları (sohbet, bildirim, canlı güncelleme) WebSocket üzerinden yürütür. İki teknoloji birbirini tamamlar; her ihtiyacı en uygun kanaldan karşılamak en verimli mimaridir.
Sonuç
WebSocket, modern uygulamaların "canlı" hissettirmesini sağlayan temel teknolojilerden biridir. Sürekli açık, çift yönlü ve düşük gecikmeli bağlantısıyla; sohbetten canlı takibe, ortak düzenlemeden anlık bildirimlere kadar geniş bir alanda kullanıcı deneyimini dönüştürür. Ancak gücü kadar sorumluluk da getirir: doğru senaryoda kullanmak, baştan ölçeklenebilir bir mimari kurmak, güvenliği ve yeniden bağlanmayı ciddiye almak başarının anahtarıdır.
KaliteliWebsite olarak İstanbul'dan, gerçek zamanlı sohbet, canlı veri akışı ve bildirim sistemlerini ölçeklenebilir ve güvenli mimarilerle kuruyoruz. Projeniz için 10.000 TL'den başlayan fiyatlar ve ücretsiz keşif görüşmesi sunuyoruz. İhtiyacınızı birlikte değerlendirip size en uygun teknik yaklaşımı belirlemek için bizimle iletişime geçebilirsiniz.