Gereksinimler ve Ön Hazırlık
Projeye başlamadan önce bilgisayarınızda Node.js'in güncel bir LTS (Long Term Support) sürümünün kurulu olması gerekir. Ayrıca, paket yönetimi için npm veya pnpm kullanacağız. Proje dizininizi oluşturun ve gerekli bağımlılıkları yükleyerek başlayın.
# Proje dizinini oluşturun
mkdir user-tracking-system
cd user-tracking-system
# Projeyi başlatın
npm init -y
# Gerekli paketleri yükleyin
npm install express socket.io
Bu adımda express web sunucumuzu oluşturmak için, socket.io ise çift yönlü iletişim (Websocket) sağlamak için kullanılacaktır. Kurulum tamamlandığında package.json dosyanızda bu bağımlılıkların yer aldığından emin olun.
Sunucu Tarafında Temel Websocket Yapılandırması
Sunucu, istemcilerden gelen bağlantıları dinlemeli ve her bağlanan kullanıcıya özel bir kimlik (ID) atamalıdır. Bu, kullanıcıları ayırt etmemizi sağlayan temel mekanizmadır. Aşağıdaki kod, basit bir HTTP sunucusu ile Websocket entegrasyonunu 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 kullanıcı bağlandı:', socket.id);
socket.on('disconnect', () => {
console.log('Kullanıcı ayrıldı:', socket.id);
});
});
server.listen(3000, () => {
console.log('Sunucu 3000 portunda çalışıyor.');
});
Bu kod bloğu, sunucuyu başlatır ve her yeni bağlantı için konsola bilgi verir. socket.id, Socket.io tarafından otomatik olarak üretilen benzersiz bir değerdir ve kullanıcıları izlemek için anahtarımız olacaktır.
İstemci Tarafında Bağlantı ve Veri Gönderimi
İstemci tarafında, sunucuya bağlanmak ve mevcut durumu (örneğin mouse konumu veya kullanıcı durumu) sunucuya iletmek için Socket.io istemci kütüphanesini kullanırız. HTML dosyanızda şu yapıyı kurun:
const socket = io();
// Kullanıcı durumunu sunucuya gönder
function updateStatus(status) {
socket.emit('user-update', { status: status, timestamp: Date.now() });
}
socket.emit metodu, belirli bir olay (event) ismiyle veri göndermemizi sağlar. Sunucu tarafında bu veriyi yakalamak için socket.on('user-update', ...) dinleyicisini eklememiz gerekecektir.
Çoklu Kullanıcı Verilerini Yönetme ve Yayınlama
Çoklu kullanıcı izleme sistemlerinde, tüm aktif kullanıcıların listesini tutmak ve yeni bağlanan kullanıcılara bu listeyi iletmek önemlidir. Bunun için sunucu tarafında bir nesne (map) kullanabiliriz.
const activeUsers = new Map();
io.on('connection', (socket) => {
socket.on('user-update', (data) => {
activeUsers.set(socket.id, data);
// Tüm kullanıcılara güncel listeyi gönder
io.emit('user-list-update', Array.from(activeUsers.entries()));
});
socket.on('disconnect', () => {
activeUsers.delete(socket.id);
io.emit('user-list-update', Array.from(activeUsers.entries()));
});
});
Burada Map yapısını kullanmamızın nedeni, ID bazlı hızlı erişim sağlamasıdır. io.emit komutu, sunucuya bağlı olan tüm istemcilere veriyi yayınlar, böylece herkes anlık olarak birbirinin durumunu görebilir.
Performans ve Ölçeklenebilirlik Karşılaştırması
Sisteminizi büyütürken aşağıdaki yöntemler arasında bir tercih yapmanız gerekebilir:
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Memory (Map) | Hızlı ve kurulumu kolay | Sunucu yeniden başlarsa veri kaybolur |
| Redis | Dağıtık sistemlere uygun | Ekstra altyapı maliyeti |
| Database (MongoDB) | Kalıcı veri sağlar | Yazma hızı Websocket'e göre yavaştır |
Güvenlik ve Üretim Ortamı İçin Kritik Uyarılar
Dikkat: Üretim ortamında (production) Websocket bağlantılarını mutlaka CORS (Cross-Origin Resource Sharing) ile sınırlandırın. Aksi takdirde, kötü niyetli web siteleri sizin sunucunuza bağlanabilir. Ayrıca, kullanıcı verilerini doğrulamadan (validation) doğrudan veritabanına veya diğer kullanıcılara göndermeyin; bu, XSS (Cross-Site Scripting) saldırılarına kapı aralar.
Güvenli bir yapılandırma için şu örneği kullanın:
const io = new Server(server, {
cors: {
origin: "https://siteniz.com",
methods: ["GET", "POST"]
}
});
Sıkça Sorulan Sorular
Websocket bağlantısı neden sürekli kopuyor?
Bu genellikle ağ kesintileri veya sunucunun "heartbeat" (kalp atışı) sinyallerini zamanında alamamasından kaynaklanır. Socket.io bu durumu otomatik yönetir ancak istemci tarafında yeniden bağlanma (reconnection) ayarlarını kontrol etmelisiniz.
Aynı anda kaç kullanıcı desteklenebilir?
Tek bir Node.js süreci genellikle 10.000 civarında eşzamanlı bağlantıyı yönetebilir. Daha fazlası için "Redis Adapter" kullanarak sunucuları yatayda ölçeklendirmeniz gerekir.
Veri güvenliğini nasıl sağlarım?
Kullanıcıların gönderdiği verileri mutlaka joi veya zod gibi kütüphanelerle doğrulayın. Ayrıca, kritik işlemlerde JWT (JSON Web Token) kullanarak bağlantı kuran kullanıcının kimliğini doğrulayın.
Neden Socket.io kullanmalıyım?
Standart WebSocket API'si yerine Socket.io kullanmak; otomatik yeniden bağlanma, oda (room) desteği ve farklı tarayıcı uyumluluklarını tek bir çatı altında sunduğu için geliştirme sürecini hızlandırır.
Bu sistem mobil cihazlarda çalışır mı?
Evet, Socket.io hem tarayıcı tabanlı hem de React Native gibi mobil platformlarda sorunsuz çalışır.
Socket.io ile Oda (Room) Tabanlı İzleme Mimarisi
Kullanıcıların tüm sunucuya değil, sadece belirli bir coğrafi bölgeye veya çalışma grubuna yayın yapmasını sağlamak, sistemin ölçeklenebilirliğini artırır. Socket.io'nun dahili Rooms özelliği, verinin sadece ilgili kanala abone olan istemcilere iletilmesini sağlar. Bu, gereksiz veri trafiğini önlemek için en etkili yöntemdir.
Oda Yönetimi ve Veri Filtreleme
Kullanıcıları bir odaya dahil etmek için join metodunu, veriyi sadece o odadakilere göndermek için ise to() metodunu kullanırız. Aşağıdaki örnekte, kullanıcıların belirli bir "proje_id" üzerinden gruplandırılması gösterilmektedir:
// Sunucu tarafında odaya katılım
io.on('connection', (socket) => {
socket.on('join_project', (projectId) => {
socket.join(projectId);
console.log(`Kullanıcı ${socket.id}, ${projectId} odasına katıldı.`);
});
// Sadece odaya özel veri yayını
socket.on('update_location', (data) => {
const { projectId, lat, lng } = data;
socket.to(projectId).emit('user_moved', { userId: socket.id, lat, lng });
});
});
Üretim Ortamında Hata Ayıklama ve İzleme (Monitoring)
Websocket bağlantıları canlı olduğu için, sistemdeki darboğazları tespit etmek geleneksel HTTP isteklerinden daha zordur. Üretim ortamında bağlantı kopmalarını ve gecikmeleri takip etmek için aşağıdaki stratejileri izlemelisiniz:
Bağlantı Sağlığı İçin İpuçları
- Heartbeat İzleme: Socket.io'nun dahili
pingTimeoutvepingIntervaldeğerlerini sunucu yükünüze göre optimize edin. - Loglama: Bağlantı hatalarını ve istemci tarafındaki
disconnectsebeplerini (örneğin:io server disconnectveyatransport close) mutlaka merkezi bir loglama servisine kaydedin. - Redis Adapter Kullanımı: Eğer birden fazla Node.js sunucusu (cluster) kullanıyorsanız, odalar arası mesajlaşmanın senkronize olması için
@socket.io/redis-adapterkullanmanız zorunludur.
İpucu: Sunucu kaynaklarını izlemek içinpm2gibi süreç yöneticileri kullanın.pm2 monitkomutu ile anlık CPU ve RAM kullanımını takip edebilir, websocket bağlantı sayısının sunucuyu ne kadar zorladığını gözlemleyebilirsiniz.
Performans Testi İçin Küçük Bir Senaryo
Sisteminizi canlıya almadan önce, binlerce sanal kullanıcı ile yük testi yapmanız gerekir. Bunun için socket.io-client kullanarak basit bir test script'i oluşturabilirsiniz:
const io = require('socket.io-client');
const users = [];
// 1000 sanal kullanıcı oluştur
for (let i = 0; i < 1000; i++) {
const socket = io('http://localhost:3000');
socket.on('connect', () => {
socket.emit('join_project', 'test_room');
});
users.push(socket);
}
console.log('1000 kullanıcı sisteme bağlandı.');
Bu test sonucunda sunucunuzun event loop süresini ve bellek tüketimini kontrol ederek, sistemin limitlerini belirleyebilir ve gerekli durumlarda dikey (vertical) veya yatay (horizontal) ölçeklendirme kararları alabilirsiniz.
Sonuç
Node.js ve Socket.io kullanarak çoklu kullanıcı izleme sistemi oluşturmak, doğru mimari kurulduğunda oldukça verimli bir süreçtir. Bu rehberde, bağlantı yönetimi, veri yayını ve temel güvenlik önlemlerini ele aldık. Bir sonraki adım olarak, kullanıcıları belirli "odalar" (rooms) içine alarak, sadece belirli bir bölgedeki veya gruptaki kullanıcıların birbirini izlemesini sağlayan "Socket.io Rooms" özelliğini araştırmanızı öneririm.
Sorumluluk reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamına almadan önce mutlaka kapsamlı güvenlik testlerinden geçirin ve kullanıcı verilerinin gizliliği konusunda KVKK standartlarına uygun hareket edin.


Yorumlar (0)
Yorum Yaz