Gereksinimler ve Ön Hazırlık
Uygulamayı geliştirmeye başlamadan önce bilgisayarınızda Node.js'in güncel bir LTS (Long Term Support) sürümünün kurulu olması gerekir. 2026 standartlarında, modüler bir yapı kurmak için npm veya pnpm paket yöneticilerini kullanacağız.
- Node.js: v20 veya üzeri bir sürüm.
- Socket.io: İstemci ve sunucu arasındaki gerçek zamanlı iletişimi sağlayan kütüphane.
- Express: HTTP sunucusu oluşturmak için gerekli olan web framework'ü.
- Kod Editörü: VS Code gibi modern bir IDE.
Proje klasörünüzü oluşturun ve gerekli bağımlılıkları yüklemek için aşağıdaki komutları terminalinizde çalıştırın:
mkdir quiz-app
cd quiz-app
npm init -y
npm install express socket.io
Bu komutlar, projenizin temel yapılandırma dosyasını (package.json) oluşturacak ve gerekli kütüphaneleri node_modules klasörüne indirecektir.
Sunucu Tarafını Yapılandırma
Node.js sunucusu, tüm oyuncuların bağlantılarını yöneten ve oyun durumunu (state) tutan merkezdir. Socket.io, HTTP sunucusu üzerinde çalışarak WebSocket bağlantılarını yönetir. Aşağıdaki kod, basit bir sunucu kurulumunu gösterir.
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);
io.on('connection', (socket) => {
console.log('Yeni bir oyuncu bağlandı:', socket.id);
socket.on('disconnect', () => {
console.log('Oyuncu ayrıldı:', socket.id);
});
});
server.listen(3000, () => {
console.log('Sunucu 3000 portunda çalışıyor.');
});
Burada io.on('connection') metodu, her yeni bağlantı kurulduğunda tetiklenir. Bu, oyun odalarına oyuncu eklemek veya onları oyun döngüsüne dahil etmek için kullandığımız ana giriş noktasıdır.
Oyun Mantığını ve Olayları Yönetme
Çok oyunculu bir bilgi yarışmasında, sunucunun "soru gönder", "cevap al" ve "skor tablosunu güncelle" gibi olayları (events) yönetmesi gerekir. Socket.io'nun emit ve on metodları bu süreçte kritik öneme sahiptir.
// Sunucu tarafında soru gönderme
function soruGonder(socket) {
const soru = { metin: "Node.js hangi dilde yazılmıştır?", cevap: "JavaScript" };
socket.emit('yeniSoru', soru);
}
// İstemciden gelen cevabı işleme
socket.on('cevapVer', (data) => {
if (data.cevap === dogruCevap) {
socket.emit('sonuc', { durum: 'dogru', puan: 10 });
} else {
socket.emit('sonuc', { durum: 'yanlis', puan: 0 });
}
});
Bu yapı, sunucunun istemciye veri göndermesini (emit) ve istemciden gelen veriyi dinlemesini (on) sağlar. Güvenlik açısından, cevapları asla istemci tarafında doğrulamayın; her zaman sunucuda kontrol edin.
İstemci Tarafı ve Gerçek Zamanlı Arayüz
İstemci tarafında Socket.io istemci kütüphanesini kullanarak sunucuya bağlanırız. Kullanıcı arayüzü, sunucudan gelen soruları anlık olarak ekrana yansıtmalıdır.
const socket = io();
socket.on('yeniSoru', (soru) => {
document.getElementById('soruAlani').innerText = soru.metin;
});
function cevapGonder(cevap) {
socket.emit('cevapVer', { cevap: cevap });
}
Bu kod bloğu, sunucudan gelen yeniSoru olayını dinler ve DOM (Document Object Model) üzerinde ilgili alanı günceller. Kullanıcı bir butona bastığında ise cevapVer olayı sunucuya iletilir.
Veri Senkronizasyonu ve Performans
Çok oyunculu sistemlerde senkronizasyon en büyük zorluktur. Her oyuncunun aynı soruyu aynı anda görmesi için io.emit veya io.to(oda).emit kullanılmalıdır. Aşağıdaki tablo, farklı iletişim yöntemlerini karşılaştırır.
| Yöntem | Kullanım Alanı | Avantajı |
|---|---|---|
| socket.emit | Bireysel | Düşük trafik, yüksek hız. |
| socket.broadcast.emit | Diğerlerine | Grup bildirimleri için ideal. |
| io.emit | Herkese | Oyun başlangıcı/bitişi için kullanılır. |
Kritik Uyarı: Üretim ortamında (production) Socket.io kullanırken, "CORS" (Cross-Origin Resource Sharing) ayarlarını mutlaka kısıtlayın. Sadece güvenilir alan adlarınızın sunucuya bağlanmasına izin verin. Ayrıca, kullanıcı girdilerini sunucuda mutlaka doğrulayın (sanitization) ve XSS (Cross-Site Scripting) saldırılarına karşı önlem alın.
Sıkça Sorulan Sorular
Socket.io ile geleneksel HTTP arasındaki temel fark nedir?
HTTP tek yönlüdür; istemci istek atar, sunucu cevap verir. Socket.io ise çift yönlü, sürekli açık bir bağlantı (WebSocket) kurar, bu sayede sunucu istemciye istediği an veri "itme" (push) yeteneğine sahip olur.
Çok fazla oyuncu bağlandığında sunucu nasıl ölçeklenir?
Socket.io'nun Redis adaptörünü kullanarak birden fazla sunucu örneği (instance) arasında mesajlaşma sağlayabilir ve yükü dağıtabilirsiniz.
Bağlantı koptuğunda ne olur?
Socket.io otomatik olarak yeniden bağlanmaya çalışır. Uygulamanızda disconnect ve reconnect olaylarını dinleyerek kullanıcının oyun durumunu koruyabilirsiniz.
Veritabanı olarak ne kullanmalıyım?
Anlık skorlar ve oyun durumu için Redis gibi bellek içi (in-memory) veritabanları, kalıcı veriler için ise MongoDB veya PostgreSQL tercih edilebilir.
Güvenlik için nelere dikkat etmeliyim?
Her zaman HTTPS kullanın. Socket.io bağlantılarını JWT (JSON Web Token) ile doğrulayarak yetkisiz erişimleri engelleyin.
Socket.io Uygulamalarında Hata Ayıklama ve İzleme Stratejileri
Gerçek zamanlı uygulamalarda hata ayıklamak, geleneksel HTTP tabanlı uygulamalara göre daha karmaşıktır çünkü bağlantıların sürekliliği ve asenkron olaylar (events) hata kaynaklarının tespitini zorlaştırır. Uygulamanızın kararlılığını artırmak için aşağıdaki yöntemleri izleyebilirsiniz.
Socket.io Debug Modunu Kullanma
Socket.io, hata ayıklama süreçlerini kolaylaştırmak için yerleşik bir debug paketi kullanır. Sunucunuzu başlatırken DEBUG ortam değişkenini ayarlayarak tüm soket trafiğini terminalinizde izleyebilirsiniz.
# Linux veya macOS üzerinde
DEBUG=socket.io:* node server.js
# Windows PowerShell üzerinde
$env:DEBUG="socket.io:*"; node server.js
Bu komut, bağlantı kurma, kopma, paket gönderimi ve hata sinyalleri dahil olmak üzere tüm arka plan işlemlerini konsola dökecektir. Üretim (production) ortamında bu özelliği kapatmayı unutmayın, aksi takdirde log dosyalarınız çok hızlı dolacaktır.
İstemci ve Sunucu Tarafı Hata Yönetimi
Bağlantı hatalarını yakalamak için hem istemci hem de sunucu tarafında özel dinleyiciler oluşturmalısınız. Özellikle ağ kesintileri durumunda uygulamanın "donmaması" için yeniden bağlanma (reconnection) mantığını optimize etmek kritiktir.
// İstemci tarafında bağlantı hatalarını yakalama
socket.on("connect_error", (err) => {
console.error("Bağlantı hatası:", err.message);
// Kullanıcıya bildirim göster
showNotification("Sunucuya bağlanılamıyor, tekrar deneniyor...");
});
// Sunucu tarafında hata yönetimi
io.on("connection", (socket) => {
socket.on("error", (err) => {
console.error("Soket hatası:", err);
});
});
Uygulamayı Canlıya Alma (Deployment) ve Ölçeklendirme
Geliştirdiğiniz bilgi yarışması uygulamasını canlı ortama alırken, Socket.io'nun doğası gereği dikkat etmeniz gereken en önemli konu "Sticky Sessions" (yapışkan oturumlar) kavramıdır. Eğer uygulamanızı birden fazla sunucu örneğinde (multi-instance) çalıştırıyorsanız, istemcinin ilk el sıkışma (handshake) işlemini yaptığı sunucuya bağlı kalması gerekir.
Nginx ve Redis Adapter Kullanımı
Birden fazla sunucu örneği kullanıyorsanız, sunucular arası iletişimi sağlamak için @socket.io/redis-adapter kullanmanız şarttır. Bu sayede bir sunucuya bağlı olan oyuncu, diğer sunucuya bağlı olan oyuncuyla aynı "oda" içinde yarışabilir.
Nginx yapılandırmanızda ise şu ayarların yapılmış olması gerekir:
upstream io_nodes {
ip_hash; # İstemcinin aynı sunucuya yönlendirilmesini sağlar
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
server {
location /socket.io/ {
proxy_pass http://io_nodes;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
Performans İçin İleri İpuçları
- Payload Boyutunu Sınırlayın: Çok büyük JSON verilerini soket üzerinden göndermek gecikmeye (latency) neden olur. Verileri mümkün olduğunca küçültün.
- Binary Veri Kullanımı: Eğer oyun içinde görsel veya ses dosyası aktarmanız gerekiyorsa, bunu base64 string yerine
BufferveyaBlobolarak gönderin. - İstemci Tarafı Filtreleme: Sunucudan gelen her veriyi DOM'a basmadan önce istemci tarafında doğrulayın.
- Heartbeat Ayarları: Yüksek trafikli uygulamalarda
pingIntervalvepingTimeoutdeğerlerini ağ koşullarınıza göre optimize edin.
Not: Uygulamanızı yayına almadan önceartilleryveyasocket.io-load-testgibi araçlarla yük testi yapmanız, sunucunuzun aynı anda kaç oyuncuyu kaldırabileceğini görmenizi sağlar.
Sonuç
Node.js ve Socket.io, gerçek zamanlı bilgi yarışması uygulamaları için endüstri standardı olan güçlü bir ikilidir. Bu rehberde, sunucu kurulumundan istemci etkileşimine kadar temel bir akışı tamamladık. Bir sonraki adım olarak, oyuncular için "Oda" (Room) mantığını kurarak, arkadaş gruplarının kendi aralarında yarışabileceği özel odalar oluşturmayı deneyebilirsiniz. Yazılım geliştirme sürecinde, her zaman güvenliği ön planda tutmayı ve kodunuzu modüler bir şekilde yazmayı unutmayın.


Yorumlar (0)
Yorum Yaz