Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce sisteminizde Node.js'in güncel bir sürümünün (2026 itibarıyla LTS sürümü önerilir) yüklü olduğundan emin olmalısınız. Paket yönetimi için npm veya pnpm kullanabilirsiniz.
- Node.js (v20 veya üzeri)
- React (Vite ile oluşturulmuş bir proje önerilir)
- Socket.io (Sunucu tarafı için)
- Socket.io-client (İstemci tarafı için)
Projenizi başlatmak için terminalinizde şu komutları çalıştırarak gerekli bağımlılıkları yükleyin:
mkdir sohbet-uygulamasi
cd sohbet-uygulamasi
npm init -y
npm install express socket.io
npm install socket.io-client
Bu komutlar, hem arka uç (backend) sunucumuzu ayağa kaldıracak Express kütüphanesini hem de gerçek zamanlı iletişim için gerekli olan Socket.io modüllerini projenize dahil edecektir.
Adım Adım Socket.io Sunucusu Kurulumu
Gerçek zamanlı bir sohbetin merkezinde, tüm istemcilerden gelen mesajları dinleyen ve bunları diğer istemcilere dağıtan bir sunucu bulunur. Node.js ve Express kullanarak basit bir soket sunucusu oluşturalım.
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:5173",
methods: ["GET", "POST"]
}
});
io.on('connection', (socket) => {
console.log('Bir kullanıcı bağlandı:', socket.id);
socket.on('mesaj_gonder', (data) => {
io.emit('mesaj_al', data);
});
});
server.listen(3001, () => {
console.log('Sunucu 3001 portunda çalışıyor');
});
Bu kod bloğu, 3001 portunda bir sunucu başlatır ve CORS (Cross-Origin Resource Sharing) ayarlarını yaparak React uygulamanızın sunucuya bağlanmasına izin verir. io.emit metodu, sunucuya gelen bir mesajı bağlı olan tüm istemcilere yayınlamak için kullanılır.
React İstemci Tarafında Socket Bağlantısı
Sunucumuz hazır olduğuna göre, şimdi React tarafında bu bağlantıyı nasıl yöneteceğimize bakalım. useEffect hook'u, bileşen yüklendiğinde bağlantıyı kurmak ve bileşen yok olduğunda bağlantıyı temizlemek için idealdir.
import { useEffect, useState } from 'react';
import io from 'socket.io-client';
const socket = io.connect('http://localhost:3001');
function App() {
const [mesaj, setMesaj] = useState('');
const [sohbet, setSohbet] = useState([]);
useEffect(() => {
socket.on('mesaj_al', (data) => {
setSohbet((prev) => [...prev, data]);
});
}, []);
const mesajGonder = () => {
socket.emit('mesaj_gonder', { metin: mesaj });
setMesaj('');
};
return (
setMesaj(e.target.value)} />
Gönder
);
}
Yukarıdaki örnekte, socket.on ile sunucudan gelen mesajları dinliyoruz ve setSohbet ile durumu güncelliyoruz. Bu sayede mesajlar anlık olarak arayüzde görünür hale gelir.
Gerçek Zamanlı İletişimde Güvenlik Önlemleri
Gerçek zamanlı uygulamalarda XSS (Cross-Site Scripting) saldırıları en büyük tehditlerden biridir. Kullanıcıdan gelen veriyi doğrudan DOM'a yazmak yerine, her zaman temizlenmiş (sanitized) veriler kullanmalısınız.
Kritik Güvenlik Uyarısı: Kullanıcı girişlerini asla doğrulamadan sunucuya göndermeyin. Sunucu tarafında mutlaka "input validation" (girdi doğrulama) uygulayın. Ayrıca, üretim ortamında (production) soket bağlantılarınızı mutlaka HTTPS üzerinden gerçekleştirin.
Aşağıdaki örnekte, mesaj gönderirken basit bir doğrulama yapıyoruz:
const mesajGonder = () => {
if (mesaj.trim() !== '') {
socket.emit('mesaj_gonder', {
metin: mesaj.replace(/]*>/g, ''),
zaman: new Date().toLocaleTimeString()
});
setMesaj('');
}
};
Performans ve Ölçeklendirme Karşılaştırması
Sohbet uygulamalarında kullanılan farklı yöntemlerin karşılaştırması aşağıdadır:
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Polling (Düzenli İstek) | Basit yapı | Sunucu yükü yüksek, gecikmeli |
| Socket.io | Düşük gecikme, otomatik bağlantı | Sunucu tarafında state yönetimi zor |
| WebRTC | P2P (Doğrudan) iletişim | Kurulumu karmaşık |
Sıkça Sorulan Sorular
Socket.io ile WebSocket arasındaki fark nedir?
WebSocket, tarayıcı ve sunucu arasında çift yönlü iletişim sağlayan bir protokoldür. Socket.io ise bu protokolü temel alan, bağlantı koptuğunda otomatik yeniden bağlanma, oda desteği ve yedekleme mekanizmaları sunan bir kütüphanedir.
Neden mesajlar bazen iki kez görünüyor?
Bu genellikle React'in "Strict Mode" özelliğinden kaynaklanır. Geliştirme aşamasında bileşenler iki kez render edildiği için soket dinleyicileri de iki kez çalışabilir. useEffect içinde temizleme (cleanup) fonksiyonu kullanarak bunu engelleyebilirsiniz.
Üretim ortamında (Production) nelere dikkat etmeliyim?
Üretim ortamında tek bir sunucu yerine Redis kullanarak soket mesajlarını dağıtmanız (pub/sub) gerekir. Bu, uygulamanızın birden fazla sunucuda ölçeklenmesini sağlar.
Özel odalar (Private Chat) nasıl oluşturulur?
Socket.io'nun socket.join('oda_adi') metodunu kullanarak kullanıcıları belirli kanallara dahil edebilir ve sadece o kanala mesaj gönderebilirsiniz.
Soket bağlantısı güvenli mi?
Soket bağlantıları, HTTP isteklerinde olduğu gibi JWT (JSON Web Token) ile korunabilir. Bağlantı kurulurken `auth` objesi üzerinden token göndererek yetkilendirme yapabilirsiniz.
Socket.io Uygulamalarında Hata Ayıklama ve İzleme (Debugging & Monitoring)
Gerçek zamanlı uygulamalarda yaşanan sorunlar genellikle ağ kopmaları, paket kayıpları veya sunucu tarafındaki olay döngüsü (event loop) tıkanıklıklarıyla ilgilidir. Uygulamanızın üretim ortamında kararlı çalışması için şu hata ayıklama stratejilerini izlemelisiniz.
İstemci Tarafında Bağlantı Durumu İzleme
React tarafında bağlantı koptuğunda kullanıcıya bilgi vermek veya otomatik yeniden bağlanma süreçlerini yönetmek kritik öneme sahiptir. Socket.io'nun sağladığı yerleşik olayları kullanarak bağlantı durumunu takip edebilirsiniz.
useEffect(() => {
socket.on("connect_error", (err) => {
console.error("Bağlantı hatası:", err.message);
});
socket.on("reconnect_attempt", (attempt) => {
console.log(`Yeniden bağlanma denemesi: ${attempt}`);
});
return () => {
socket.off("connect_error");
socket.off("reconnect_attempt");
};
}, [socket]);
Sunucu Tarafında Debug Modu
Geliştirme aşamasında Socket.io'nun içsel süreçlerini görmek için DEBUG ortam değişkenini kullanabilirsiniz. Bu, paketlerin nasıl işlendiğini ve hangi olayların tetiklendiğini terminalinizde görmenizi sağlar.
# Terminal üzerinde çalıştırma
DEBUG=socket.io:* node server.js
Socket.io Uygulamalarını Yayına Alma (Deployment) İpuçları
Uygulamanızı yerel ortamdan canlı sunucuya taşırken, WebSocket bağlantılarının doğası gereği dikkat etmeniz gereken birkaç temel yapılandırma bulunmaktadır. Özellikle Nginx gibi bir ters vekil sunucu (reverse proxy) kullanıyorsanız, WebSocket yükseltme (upgrade) başlıklarını doğru yapılandırmanız gerekir.
Nginx WebSocket Yapılandırması
Nginx kullanıyorsanız, bağlantının kesilmemesi için aşağıdaki ayarları location bloğunuza eklemelisiniz:
location /socket.io/ {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
Ölçeklendirme ve Redis Adaptörü
Uygulamanız büyüdüğünde tek bir sunucu yetersiz kalacaktır. Birden fazla sunucu (instance) çalıştırdığınızda, bir sunucuya bağlı olan kullanıcı diğer sunucudaki kullanıcıya mesaj gönderemez. Bu sorunu aşmak için Redis Adapter kullanarak olayları tüm sunucular arasında yayınlamanız (pub/sub) gerekir.
const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");
const pubClient = createClient({ url: "redis://localhost:6379" });
const subClient = pubClient.duplicate();
io.adapter(createAdapter(pubClient, subClient));
Not: Redis kullanımı, mesajların tüm sunucu örnekleri arasında senkronize edilmesini sağlar ve uygulamanızın yatayda ölçeklenebilir (horizontal scaling) olmasını mümkün kılar.
Test Süreçleri ve Yük Testi
Uygulamanızın eşzamanlı kaç kullanıcıyı kaldırabileceğini test etmek için socket.io-client ile basit bir yük testi betiği yazabilirsiniz. Bu betik, binlerce sahte kullanıcı oluşturarak sunucunun bellek ve CPU kullanımını gözlemlemenize yardımcı olur.
- Birim Testleri: Olay dinleyicilerinin (event listeners) doğru tetiklendiğini doğrulamak için Jest kullanın.
- Entegrasyon Testleri: İstemci ve sunucu arasındaki el sıkışma (handshake) sürecini test edin.
- Yük Testi: Artillery veya benzeri araçlarla WebSocket bağlantı limitlerinizi belirleyin.
Sonuç
React ve Socket.io kullanarak gerçek zamanlı bir sohbet uygulaması oluşturmak, modern web geliştirme süreçlerinde temel bir yetkinliktir. Bu rehberde, sunucu kurulumundan istemci tarafındaki veri akışına ve güvenlik önlemlerine kadar kritik adımları inceledik. Bir sonraki adım olarak, bu projeye veritabanı (MongoDB gibi) entegre ederek mesaj geçmişini saklamayı ve kullanıcı kimlik doğrulama sistemlerini eklemeyi deneyebilirsiniz.
Yasal Uyarı: Bu makalede paylaşılan kod örnekleri eğitim amaçlıdır. Ticari projelerinizde kullanmadan önce güvenlik açıklarını (OWASP standartları) gözden geçirmeli ve profesyonel bir güvenlik denetiminden geçirmelisiniz.


Yorumlar (0)
Yorum Yaz