Node.js İle Socket.io Kullanarak Canlı Bildirim Sistemi Nasıl Yapılır?

Node.js İle Socket.io Kullanarak Canlı Bildirim Sistemi Nasıl Yapılır?
Node.js İle Socket.io Kullanarak Canlı Bildirim Sistemi Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce sisteminizde Node.js'in güncel bir LTS (Long Term Support) sürümünün kurulu olması gerekmektedir. 2026 yılı standartlarına göre Node.js 22.x veya üzeri bir sürüm kullanmanızı öneririm. Ayrıca projenizi yönetmek için bir terminal (CLI) ve kod editörü (VS Code gibi) hazır olmalıdır.

Öncelikle proje dizinini oluşturun ve gerekli paketleri yükleyerek işe başlayalım:

# Proje dizinini oluşturun
mkdir canli-bildirim-sistemi
cd canli-bildirim-sistemi

# Node.js projesini başlatın
npm init -y

# Gerekli bağımlılıkları kurun
npm install express socket.io cors

Bu komutlar, projenizin temel iskeletini oluşturur. Express, HTTP sunucumuzu yönetmek için; Socket.io ise WebSocket protokolünü kolayca yönetmemizi sağlayan kütüphanedir. CORS (Cross-Origin Resource Sharing) ise farklı alan adlarından gelen istekleri güvenli bir şekilde yönetmemize yardımcı olur.

Sunucu Tarafı Yapılandırması

Canlı bildirim sisteminin kalbi, istemcilerden gelen bağlantıları dinleyen ve gerektiğinde bu bağlantılara mesaj gönderen bir Node.js sunucusudur. Aşağıdaki kod bloğu, temel bir HTTP sunucusu ile Socket.io entegrasyonunu göstermektedir.

const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const cors = require('cors');

const app = express();
app.use(cors());

const server = http.createServer(app);
const io = new Server(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST"]
  }
});

io.on('connection', (socket) => {
  console.log('Yeni bir kullanıcı bağlandı: ', socket.id);

  socket.on('disconnect', () => {
    console.log('Kullanıcı ayrıldı');
  });
});

server.listen(4000, () => {
  console.log('Sunucu 4000 portunda çalışıyor.');
});

Bu kodda io.on('connection') metodu, her yeni bağlantıda tetiklenir. socket.id, sunucuya bağlanan her istemci için benzersiz bir tanımlayıcıdır. Bu ID'yi kullanarak belirli bir kullanıcıya özel bildirimler gönderebilirsiniz.

İstemci Tarafı Entegrasyonu

Sunucumuz hazır olduğuna göre, şimdi tarayıcı tarafında bu bildirimleri dinleyecek olan istemciyi hazırlayalım. İstemci tarafında socket.io-client paketini kullanacağız.

// İstemci tarafı bağlantı örneği
import { io } from "socket.io-client";

const socket = io("http://localhost:4000");

socket.on("connect", () => {
  console.log("Sunucuya bağlandık, ID:", socket.id);
});

socket.on("yeni-bildirim", (data) => {
  console.log("Gelen bildirim:", data.mesaj);
  alert("Yeni Bildirim: " + data.mesaj);
});

Burada socket.on("yeni-bildirim", ...) yapısı, sunucudan gelecek olan özel bir "yeni-bildirim" olayını dinler. Sunucu bu olayı tetiklediğinde, tarayıcı tarafında ilgili fonksiyon çalışacaktır.

Bildirim Gönderme Mekanizması

Sistemin en önemli parçası, bildirimlerin nasıl tetiklendiğidir. Genellikle bir veritabanı işlemi veya bir API isteği sonucunda bildirim tetiklenir. Aşağıdaki örnekte, bir API rotası üzerinden tüm bağlı kullanıcılara nasıl bildirim gönderileceğini görebilirsiniz.

// Express rotası üzerinden bildirim tetikleme
app.post('/bildirim-gonder', (req, res) => {
  const { mesaj, kullaniciId } = req.body;

  // Tüm kullanıcılara gönder
  io.emit('yeni-bildirim', { mesaj: mesaj });

  res.status(200).send({ status: 'Bildirim gönderildi' });
});

io.emit komutu, sunucuya bağlı olan tüm istemcilere aynı mesajı yayınlar. Eğer sadece belirli bir kullanıcıya bildirim göndermek isterseniz, socket.to(kullaniciId).emit(...) yöntemini kullanmalısınız.

Canlı Bildirim Sistemlerinde Güvenlik ve Performans

Gerçek zamanlı sistemlerde güvenlik, en az performans kadar önemlidir. Özellikle kullanıcıların kimlik doğrulaması (authentication) yapılmadan bildirim kanallarına erişimine izin verilmemelidir.

Kritik Uyarı: Üretim ortamında (production) Socket.io bağlantılarını mutlaka JWT (JSON Web Token) ile koruyun. Aksi takdirde, kötü niyetli kişiler sunucunuza sahte bildirim istekleri gönderebilir veya diğer kullanıcıların bildirimlerini dinleyebilir.

Aşağıdaki tablo, bildirim sistemlerinde kullanılan yöntemlerin kısa bir karşılaştırmasını sunar:

Yöntem Avantaj Dezavantaj
Polling (Sorgulama) Basit kurulum Yüksek sunucu yükü, gecikme
Socket.io (WebSocket) Anlık, düşük gecikme Stateful (durum bilgisi tutan) yapı
Server-Sent Events Tek yönlü, hafif Sadece sunucudan istemciye

Hata Ayıklama ve Yaygın Sorunlar

Geliştirme sürecinde en sık karşılaşılan sorunlardan biri CORS hatalarıdır. Eğer istemciniz sunucuya bağlanamıyorsa, sunucu tarafındaki cors ayarlarını kontrol edin. Ayrıca, WebSocket bağlantısının kesilmesi durumunda otomatik yeniden bağlanma (reconnection) mekanizmalarını Socket.io kendi içerisinde yönetir, ancak bu süreleri özelleştirmek için konfigürasyon yapabilirsiniz.

// Yeniden bağlanma ayarları
const io = new Server(server, {
  reconnectionAttempts: 5,
  reconnectionDelay: 1000
});

Sıkça Sorulan Sorular

Socket.io ile WebSocket arasındaki fark nedir?

WebSocket, tarayıcı ve sunucu arasında çift yönlü bir iletişim protokolüdür. Socket.io ise bu protokolü temel alan, kopan bağlantıları otomatik yöneten, fallback (yedekleme) mekanizmaları sunan ve kullanımı kolaylaştıran bir kütüphanedir.

Canlı bildirimler veritabanına kaydedilmeli mi?

Evet, bildirimlerin kalıcı olması için veritabanına kaydedilmesi önerilir. Socket.io sadece anlık iletimi sağlar; kullanıcı çevrimdışıysa bildirimleri daha sonra veritabanından çekerek göstermelisiniz.

Aynı anda kaç kullanıcı destekleyebilirim?

Tek bir Node.js örneği, donanıma bağlı olarak binlerce bağlantıyı yönetebilir. Ancak ölçeklenebilirlik için Redis kullanarak "pub/sub" yapısı kurmanız ve Socket.io sunucularını yatayda (horizontal scaling) çoğaltmanız gerekir.

Bildirimleri nasıl özelleştirebilirim?

Socket.io içerisinde "namespace" ve "room" yapılarını kullanarak bildirimleri kategorize edebilir, sadece belirli gruplara veya kullanıcılara özel kanallar oluşturabilirsiniz.

Güvenlik için nelere dikkat etmeliyim?

Girdi temizliği (sanitization) yaparak XSS saldırılarını önleyin. Ayrıca, sunucu tarafında gelen tüm veriyi doğrulamadan (validation) istemcilere yayınlamayın.

Socket.io ile Ölçeklenebilir Bildirim Mimarisi: Redis Adapter Kullanımı

Tek bir sunucu üzerinde çalışan Socket.io uygulamaları, kullanıcı sayısı arttıkça darboğaz yaşamaya başlar. Uygulamanızı birden fazla sunucuya (horizontal scaling) yaydığınızda, bir sunucuya bağlı olan kullanıcı, diğer sunucuya bağlı olan kullanıcıya bildirim gönderemez. Bu sorunu çözmek için Redis Adapter kullanarak tüm sunucuları birbirine bağlayan bir "mesajlaşma hattı" oluşturmalıyız.

Redis, tüm sunucular arasındaki mesaj trafiğini yöneterek, bir sunucuya gelen bildirimin tüm bağlı istemcilere (hangi sunucuda olurlarsa olsunlar) iletilmesini sağlar.

// Sunucu tarafında Redis Adapter kurulumu
const { createClient } = require('redis');
const { createAdapter } = require('@socket.io/redis-adapter');

const pubClient = createClient({ url: 'redis://localhost:6379' });
const subClient = pubClient.duplicate();

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  io.adapter(createAdapter(pubClient, subClient));
  console.log('Redis Adapter başarıyla bağlandı.');
});

Canlı Bildirim Sistemlerinde Yük Testi ve İzleme

Sisteminizi canlıya almadan önce, yüksek trafik altında nasıl tepki verdiğini ölçmek kritik öneme sahiptir. Socket.io uygulamalarında performans darboğazlarını tespit etmek için Artillery gibi araçlar kullanarak simüle edilmiş binlerce eşzamanlı bağlantı oluşturabilirsiniz.

Performans Optimizasyonu İçin İpuçları

  • Binary Veri Kullanımı: Bildirim yükünü azaltmak için JSON yerine MessagePack gibi daha kompakt formatlar tercih edebilirsiniz.
  • Namespace Ayrımı: Tüm bildirimleri tek bir kanaldan göndermek yerine, kullanıcı rollerine veya bildirim tiplerine göre io.of('/notifications') gibi farklı namespace'ler kullanın.
  • Heartbeat Ayarları: Bağlantı kopmalarını önlemek için pingTimeout ve pingInterval değerlerini ağ koşullarınıza göre optimize edin.
// Socket.io yapılandırmasında performans ayarları
const io = require('socket.io')(server, {
  pingTimeout: 60000, // 60 saniye
  pingInterval: 25000, // 25 saniye
  transports: ['websocket'] // Polling yerine doğrudan WebSocket kullanımı
});

İzleme (Monitoring)

Sisteminizin sağlığını takip etmek için Socket.io Admin UI kütüphanesini kullanabilirsiniz. Bu araç, canlı bağlantı sayılarını, odalardaki kullanıcıları ve mesaj trafiğini görselleştirmenize olanak tanır. Ayrıca, Redis üzerinden geçen mesaj trafiğini redis-cli monitor komutu ile gerçek zamanlı olarak izleyerek sistemin yük dağılımını analiz edebilirsiniz.

Sonuç

Node.js ve Socket.io kullanarak canlı bildirim sistemi kurmak, modern web uygulamaları için standart ve oldukça güçlü bir yaklaşımdır. Bu rehberde, temel bağlantıdan bildirim gönderme mekanizmasına ve güvenlik önlemlerine kadar gerekli adımları tamamladınız. Bir sonraki adım olarak, bildirimlerinizi bir Redis veritabanı ile entegre ederek ölçeklenebilir bir yapıya dönüştürmeyi ve kullanıcılar için bildirim geçmişi (notification history) tutan bir API geliştirmeyi deneyebilirsiniz.

Yasal Uyarı ve Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce tüm girdileri doğrulamalı, kimlik doğrulama mekanizmalarını (JWT, OAuth vb.) eksiksiz uygulamalı ve sunucu güvenliğinizi profesyonel standartlarda yapılandırmalısınız.

Bu yazıya tepkinizi paylaşın:
Mert Demir

Hobi projeleri, küçük tamirat işleri ve bahçe bakımı konusunda deneyimli bir editörüm. Adım adım rehberlerimle okuyucularımın özgüvenli bir şekilde yeni beceriler kazanmasını amaçlıyorum.

Yorumlar (0)

Yorum Yaz