Gereksinimler ve Ortam Kurulumu
Projeye başlamadan önce bilgisayarınızda 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. Ayrıca bir paket yöneticisi olan npm (Node Package Manager) kurulumun bir parçası olarak gelecektir.
- Node.js: Sunucu tarafında JavaScript çalıştırmak için temel ortam.
- Express: HTTP sunucusu oluşturmak için kullanılan minimalist framework.
- Socket.io: WebSocket iletişimini kolaylaştıran, hata toleransı yüksek kütüphane.
- Kod Editörü: VS Code gibi modern bir editör.
Proje klasörünüzü oluşturun ve terminal üzerinden gerekli paketleri yüklemek için aşağıdaki komutları sırasıyla çalıştırın:
mkdir canli-karakter-ekrani
cd canli-karakter-ekrani
npm init -y
npm install express socket.io
Bu komutlar, projenizin temel dizinini oluşturacak ve gerekli bağımlılıkları node_modules klasörüne ekleyecektir. package.json dosyanızın güncellendiğini teyit edin.
Sunucu Tarafında Socket.io Kurulumu
Sunucu tarafında, Express ile bir HTTP sunucusu başlatıp, Socket.io'yu bu sunucuya bağlamamız gerekir. Socket.io, HTTP üzerinden gelen bağlantıları dinleyerek WebSocket bağlantısına yükseltir (upgrade) ve çift yönlü iletişimi sağlar.
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);
app.use(express.static('public'));
io.on('connection', (socket) => {
console.log('Bir kullanıcı bağlandı: ' + socket.id);
socket.on('karakterHareketi', (data) => {
// Gelen veriyi diğer tüm bağlı istemcilere yayınla
socket.broadcast.emit('karakterGuncelle', data);
});
});
server.listen(3000, () => {
console.log('Sunucu http://localhost:3000 adresinde çalışıyor.');
});
Bu kodda, io.on('connection', ...) bloğu, yeni bir istemci bağlandığında tetiklenir. socket.on('karakterHareketi', ...) ise istemciden gelen hareket verisini yakalar ve socket.broadcast.emit ile gönderen hariç herkese iletir.
İstemci Tarafı: HTML ve Canvas Yapısı
Karakterin görselleştirilmesi için HTML5 Canvas API'sini kullanacağız. public adında bir klasör oluşturun ve içine index.html dosyasını ekleyin. Canvas, tarayıcı üzerinde pikselleri çizmemize olanak tanıyan performanslı bir yöntemdir.
Bu yapı, karakterin hareket edeceği alanı belirler. /socket.io/socket.io.js yolu, Socket.io'nun sunucu tarafından otomatik olarak sağlanan istemci kütüphanesidir.
Karakter Hareketlerini Socket.io ile Senkronize Etme
Şimdi public/client.js dosyasını oluşturarak kullanıcı girişlerini dinleyelim ve bunları sunucuya gönderelim. Klavye olaylarını dinleyerek karakterin koordinatlarını güncelleyeceğiz.
const socket = io();
const canvas = document.getElementById('oyunAlani');
const ctx = canvas.getContext('2d');
let karakter = { x: 50, y: 50 };
function ciz() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(karakter.x, karakter.y, 50, 50);
}
window.addEventListener('keydown', (e) => {
if(e.key === 'ArrowRight') karakter.x += 10;
if(e.key === 'ArrowLeft') karakter.x -= 10;
ciz();
socket.emit('karakterHareketi', karakter);
});
socket.on('karakterGuncelle', (yeniKonum) => {
karakter = yeniKonum;
ciz();
});
Bu kod, klavye tuşlarına basıldığında karakterin konumunu günceller ve socket.emit ile sunucuya gönderir. Aynı zamanda sunucudan gelen güncellemeleri dinleyerek karakteri ekrana çizer.
Gerçek Zamanlı İletişim Yöntemlerinin Karşılaştırılması
Gerçek zamanlı veri iletimi için farklı yöntemler mevcuttur. Socket.io'nun neden tercih edildiğini aşağıdaki tabloda özetledik:
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Polling | Basit yapı | Yüksek gecikme ve trafik |
| WebSockets | Çift yönlü, çok hızlı | Düşük seviyeli yönetim gerektirir |
| Socket.io | Otomatik yeniden bağlanma, fallback | Ekstra kütüphane boyutu |
Güvenlik ve Performans Uyarıları
Kritik Uyarı: Üretim ortamında (production) Socket.io kullanırken, gelen verileri mutlaka doğrulayın. İstemciden gelen veriye güvenmek XSS (Cross-Site Scripting) veya kötü niyetli veri enjeksiyonuna yol açabilir. Ayrıca, sunucu tarafında hız sınırlaması (rate limiting) uygulayarak aşırı yüklenmelerin önüne geçin.
Kullanıcıların rastgele veri göndermesini engellemek için sunucu tarafında bir doğrulama katmanı eklemek, uygulamanızın güvenliğini artıracaktır.
Sıkça Sorulan Sorular
Socket.io her tarayıcıda çalışır mı?
Evet, Socket.io WebSocket desteği olmayan tarayıcılarda otomatik olarak HTTP Long Polling yöntemine geçiş yapar, bu sayede geniş bir uyumluluk sağlar.
Karakter hareketlerinde neden gecikme (lag) yaşıyorum?
Gecikmeler genellikle ağ yoğunluğundan veya sunucuya gönderilen veri miktarından kaynaklanır. Hareket verilerini saniyede 60 kez yerine, daha optimize edilmiş aralıklarla göndermeyi deneyin.
Birden fazla karakteri nasıl yönetirim?
Her kullanıcıya benzersiz bir socket.id atayarak, sunucuda bir nesne içerisinde her kullanıcının konumunu tutmalı ve tüm istemcilere bu nesneyi göndermelisiniz.
Üretim ortamında SSL/TLS gerekli mi?
Evet, verilerin güvenli iletimi ve tarayıcıların WebSocket bağlantılarına izin vermesi için HTTPS protokolü kullanılmalıdır.
Socket.io yerine neden doğrudan WebSocket kullanmıyoruz?
Socket.io, bağlantı kopması durumunda otomatik yeniden bağlanma ve odalar (rooms) gibi gelişmiş özellikler sunarak geliştirme sürecini ciddi oranda hızlandırır.
Socket.io Uygulamalarında Hata Ayıklama ve İzleme Stratejileri
Gerçek zamanlı uygulamalar geliştirirken karşılaşılan en büyük zorluk, istemci ve sunucu arasındaki bağlantı kopukluklarını veya veri senkronizasyon hatalarını tespit etmektir. Socket.io, hata ayıklama sürecini kolaylaştırmak için yerleşik bir "debug" mekanizmasına sahiptir.
Debug Modunu Aktif Etme
Geliştirme aşamasında sunucu tarafındaki olayları izlemek için DEBUG ortam değişkenini kullanabilirsiniz. Bu, tüm paket alışverişini konsola dökmenizi sağlar:
# Linux/macOS üzerinde
DEBUG=socket.io* node server.js
# Windows (PowerShell) üzerinde
$env:DEBUG="socket.io*"; node server.js
Bu komut, bağlantı kurma, kopma ve mesajlaşma süreçlerini detaylı bir şekilde terminale yansıtır. Eğer istemci tarafında sorun yaşıyorsanız, tarayıcı konsoluna localStorage.debug = 'socket.io-client:*'; komutunu yazarak istemci loglarını da tarayıcı üzerinden takip edebilirsiniz.
Uygulamayı Yayına Alma (Deployment) ve Ölçeklendirme
Projenizi yerel ortamdan canlı bir sunucuya taşırken, WebSocket bağlantılarının sürekliliği için dikkat etmeniz gereken kritik noktalar vardır. Özellikle Nginx gibi bir ters vekil sunucu (reverse proxy) kullanıyorsanız, WebSocket bağlantılarının yükseltilmesine (upgrade) izin vermeniz gerekir.
Nginx Konfigürasyonu
Socket.io'nun düzgün çalışması için Nginx ayarlarınızda Upgrade ve Connection başlıklarını doğru yapılandırmalısınız:
location /socket.io/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
Ölçeklendirme Sorunu ve Redis Adaptörü
Uygulamanız büyüdüğünde ve birden fazla sunucu (instance) çalıştırmanız gerektiğinde, Socket.io sunucuları birbirlerinden habersiz kalır. Bu durumu çözmek için @socket.io/redis-adapter kullanarak tüm sunucuları bir Redis veritabanı üzerinden senkronize etmelisiniz:
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));
Bu yapılandırma, bir sunucuya bağlı olan kullanıcının gönderdiği verinin, diğer sunuculara bağlı olan kullanıcılara da iletilmesini sağlar. Böylece yatay ölçeklendirme (horizontal scaling) yaparken gerçek zamanlı iletişimin kopmamasını garantilemiş olursunuz.
Performans Optimizasyonu İçin İleri İpuçları
Karakter hareketleri gibi sürekli veri akışı gerektiren durumlarda, ağ trafiğini azaltmak için şu yöntemleri uygulayabilirsiniz:
- Throttling (Kısıtlama): İstemci tarafında her mouse hareketinde sunucuya paket göndermek yerine, belirli bir milisaniye aralığıyla (örneğin 50ms) veri gönderin.
- Binary Veri Kullanımı: JSON yerine
ArrayBufferveyaBufferkullanarak veri boyutunu küçültün. - Namespace Kullanımı: Uygulamanızın farklı bölümleri için (sohbet, oyun, bildirim) ayrı namespace'ler tanımlayarak gereksiz olay tetiklemelerini engelleyin.
// İstemci tarafında hareket kısıtlama örneği
let lastEmit = 0;
canvas.addEventListener('mousemove', (e) => {
const now = Date.now();
if (now - lastEmit > 50) {
socket.emit('move', { x: e.clientX, y: e.clientY });
lastEmit = now;
}
});
Sonuç
Node.js ve Socket.io kullanarak paylaşımlı canlı karakter ekranı oluşturmak, gerçek zamanlı web teknolojilerinin temelini anlamak için harika bir başlangıçtır. Bu projeyi geliştirmek için bir sonraki adımda, birden fazla karakterin aynı ekranda görünmesini sağlayacak "Oda (Room)" mantığını ve kullanıcıların isimlerini ekrana yazdırmayı deneyebilirsiniz. Kodlarınızı her zaman güncel tutun ve güvenlik açıklarına karşı dikkatli olun.
Yasal Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Ticari projelerinizde kullanmadan önce güvenlik denetimlerini yapmalı ve profesyonel yazılım geliştirme standartlarına uygun olarak test etmelisiniz.

Yorumlar (0)
Yorum Yaz