Node.js İle Socket.io Kullanarak Canlı Veri Görselleştirme Paneli Nasıl Yapılır?

Gereksinimler ve Ön Hazırlık

Projeye başlamadan önce sisteminizde Node.js'in en güncel LTS (Long Term Support) sürümünün yüklü olduğundan emin olmalısınız. 2026 yılı standartlarına göre Node.js 22+ sürümü önerilmektedir.

  • Node.js: Sunucu tarafı çalışma ortamı.
  • npm veya pnpm: Paket yöneticisi.
  • Socket.io: WebSocket protokolü üzerinde çalışan, olay tabanlı iletişim kütüphanesi.
  • Express: Web sunucusu oluşturmak için kullanılan framework.
  • Chart.js: Verileri görselleştirmek için kullanılacak hafif ve güçlü bir kütüphane.

Terminalinizde yeni bir klasör oluşturun ve projenizi başlatın:

mkdir canlı-veri-paneli
cd canlı-veri-paneli
npm init -y
npm install express socket.io

Bu komutlar, projenizin temel yapılandırmasını oluşturacak ve gerekli bağımlılıkları yükleyecektir. package.json dosyanızda "type": "module" ibaresini ekleyerek ES Modüllerini (import/export) kullanmanızı tavsiye ederim.

Sunucu Tarafında Socket.io Kurulumu

Sunucu tarafında, veriyi üreten ve bunu bağlı olan tüm istemcilere yayınlayan (emit) bir yapı kuracağız. Socket.io, bağlantı kopmalarında otomatik yeniden bağlanma ve mesajlaşma gibi karmaşık süreçleri bizim yerimize yönetir.

import express from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';

const app = express();
const server = createServer(app);
const io = new Server(server);

io.on('connection', (socket) => {
    console.log('Bir kullanıcı bağlandı: ' + socket.id);
    
    // İstemciye düzenli aralıklarla veri gönder
    setInterval(() => {
        const rastgeleVeri = Math.floor(Math.random() * 100);
        socket.emit('veri-guncelleme', { deger: rastgeleVeri, zaman: new Date() });
    }, 2000);
});

server.listen(3000, () => {
    console.log('Sunucu http://localhost:3000 adresinde çalışıyor.');
});

Yukarıdaki kod, her iki saniyede bir rastgele bir sayı üretir ve bağlı olan tüm istemcilere veri-guncelleme olayı üzerinden bu veriyi iletir.

İstemci Tarafında Veri Karşılama

İstemci tarafında, sunucudan gelen veriyi dinlemeli ve bu veriyi görselleştirmeliyiz. Bunun için basit bir HTML dosyası ve Socket.io istemci kütüphanesini kullanacağız.



    const socket = io();
    socket.on('veri-guncelleme', (data) => {
        console.log('Yeni veri geldi:', data);
        // Burada grafik güncelleme fonksiyonu çağrılacak
    });

Bu kod bloğu, sunucudan yayınlanan mesajları yakalar. /socket.io/socket.io.js yolu, Socket.io sunucusu tarafından otomatik olarak sunulur, bu nedenle ayrıca indirmenize gerek yoktur.

Chart.js ile Veri Görselleştirme

Gelen veriyi anlamlı kılmak için Chart.js kütüphanesini kullanacağız. Veri geldikçe grafik dizisine yeni veriyi ekleyip tabloyu yeniden çizeceğiz.

const ctx = document.getElementById('grafik').getContext('2d');
const grafik = new Chart(ctx, {
    type: 'line',
    data: {
        labels: [],
        datasets: [{ label: 'Canlı Sensör Verisi', data: [] }]
    }
});

socket.on('veri-guncelleme', (data) => {
    grafik.data.labels.push(data.zaman.toLocaleTimeString());
    grafik.data.datasets[0].data.push(data.deger);
    if (grafik.data.labels.length > 20) { // Sadece son 20 veriyi tut
        grafik.data.labels.shift();
        grafik.data.datasets[0].data.shift();
    }
    grafik.update();
});

Bu yöntem, bellek sızıntısını engellemek adına eski verileri diziden kaldırarak grafiğin sürekli temiz kalmasını sağlar.

Teknik Karşılaştırma: WebSocket vs HTTP Polling

Özellik WebSocket (Socket.io) HTTP Polling
Gecikme Çok Düşük (Gerçek zamanlı) Yüksek
Sunucu Yükü Düşük (Sürekli bağlantı) Yüksek (Sürekli istek)
Çift Yönlü Evet Hayır

Güvenlik ve Performans Uyarıları

Kritik Uyarı: Canlı veri panellerinde XSS (Cross-Site Scripting) saldırılarına karşı dikkatli olunmalıdır. Sunucudan gelen veriyi doğrudan DOM'a yazdırırken textContent kullanın. Ayrıca, üretim ortamında (production) mutlaka CORS politikalarını sınırlandırın ve sadece güvenilir alan adlarının soket bağlantısı kurmasına izin verin.

Üretim ortamında Socket.io kullanırken, ölçeklenebilirlik için Redis adapter kullanmanız önerilir. Bu sayede birden fazla sunucu örneği (instance) arasında mesajlaşma senkronize edilir.

Sıkça Sorulan Sorular

Socket.io bağlantısı neden sürekli kopuyor?

Bu genellikle CORS ayarlarının yapılmamasından veya istemci ile sunucu arasındaki zaman aşımı (timeout) değerlerinin uyuşmazlığından kaynaklanır. Sunucu tarafında cors: { origin: "*" } ayarını kontrol edin.

Grafik çok fazla veri ile kasıyor, ne yapmalıyım?

Grafik kütüphanelerinde veri setini sınırlayın. Yukarıdaki örnekte olduğu gibi shift() metodu ile eski verileri diziden silmek, DOM üzerindeki yükü ciddi oranda azaltır.

Bu yapıyı veritabanı ile nasıl bağlarım?

Socket.io olayının içinde veritabanı sorgusu yapmak yerine, veritabanına yazma işlemini ayrı bir servis ile yapın. Socket.io, veritabanındaki değişimleri (Change Streams gibi) dinleyerek istemciye bildirmelidir.

Socket.io yerine neden standart WebSocket kullanmıyoruz?

Socket.io; otomatik yeniden bağlanma, fallback mekanizmaları (WebSocket desteklemeyen tarayıcılar için) ve oda (room) tabanlı mesajlaşma gibi gelişmiş özellikleri dahili olarak sunar.

Üretim ortamında güvenliği nasıl sağlarım?

HTTPS kullanmak zorunludur. Ayrıca Socket.io bağlantılarını JWT (JSON Web Token) ile doğrulayarak, sadece yetkili kullanıcıların veriyi görmesini sağlayabilirsiniz.

İleri Seviye Optimizasyon: Veri Akışını Yönetmek

Canlı veri panellerinde en büyük darboğaz, istemcinin saniyede onlarca kez güncellenen veriyi render etmeye çalışırken tarayıcıyı yormasıdır. Bu durumu engellemek için "Throttling" ve "Buffering" tekniklerini kullanmalısınız. Sunucudan gelen her paketi anında grafiğe işlemek yerine, veriyi belirli aralıklarla (örneğin 500ms'de bir) toplu şekilde işlemek performansı ciddi oranda artırır.

Aşağıdaki örnekte, gelen verileri bir dizi içerisinde biriktirip belirli aralıklarla grafiğe yansıtan bir yapı görebilirsiniz:

// İstemci tarafında veri biriktirme mantığı
let dataBuffer = [];
const BATCH_INTERVAL = 500; // ms

socket.on('live-data', (data) => {
    dataBuffer.push(data);
});

setInterval(() => {
    if (dataBuffer.length > 0) {
        // Buffer'daki verileri tek seferde grafiğe işle
        updateChart(dataBuffer);
        dataBuffer = []; // Buffer'ı temizle
    }
}, BATCH_INTERVAL);

Üretim Ortamında Ölçeklenebilirlik: Redis Adapter Kullanımı

Uygulamanız büyüdüğünde tek bir Node.js sunucusu yeterli gelmeyecektir. Birden fazla sunucu (load balancer arkasında) kullandığınızda, bir sunucuya bağlı olan istemci, diğer sunucudan gelen veriyi göremez. Bu sorunu çözmek için Socket.io Redis Adapter kullanmanız gerekir. Bu yapı, tüm sunucuların birbirleriyle haberleşmesini ve olayları (events) senkronize etmesini sağlar.

Kurulum ve konfigürasyon için şu adımları izleyebilirsiniz:

  1. Redis sunucusunu sisteminize kurun veya bir bulut servisi üzerinden edinin.
  2. @socket.io/redis-adapter ve redis paketlerini projenize dahil edin.
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));
});

Bu yapı sayesinde, uygulamanızı PM2 veya Kubernetes üzerinde yatay olarak ölçeklendirebilir, binlerce eşzamanlı bağlantıyı farklı sunuculara dağıtarak kesintisiz bir canlı veri deneyimi sunabilirsiniz.

Hata Ayıklama ve İzleme Stratejileri

Canlı sistemlerde bağlantı kopmaları veya veri kaybı yaşandığında durumu analiz etmek kritik öneme sahiptir. Socket.io'nun dahili debug modunu kullanarak trafiği izleyebilirsiniz. Terminalinizde şu komutu çalıştırarak tüm socket trafiğini konsola dökebilirsiniz:

# Linux/macOS
DEBUG=socket.io:* node server.js

# Windows (PowerShell)
$env:DEBUG="socket.io:*"; node server.js

Ayrıca, istemci tarafında bağlantı durumunu takip etmek için aşağıdaki event'leri mutlaka dinleyin:

socket.on("connect_error", (err) => {
    console.error("Bağlantı hatası:", err.message);
});

socket.on("reconnect_attempt", (attempt) => {
    console.log("Yeniden bağlanma denemesi:", attempt);
});
İpucu: Üretim ortamında console.log yerine Winston veya Pino gibi loglama kütüphaneleri kullanarak hataları merkezi bir log sunucusuna (ELK Stack veya Datadog gibi) göndermeniz, sistemin sağlığını takip etmenizi kolaylaştıracaktır.

Sonuç

Node.js ve Socket.io kullanarak canlı bir veri görselleştirme paneli oluşturmak, modern web geliştirme süreçlerinin temel taşlarından biridir. Bu rehberde, sunucu tarafında veri akışını yönetmeyi, istemci tarafında bu veriyi karşılamayı ve grafik kütüphaneleriyle görselleştirmeyi öğrendiniz. Bir sonraki adımda, bu paneli bir veritabanı (örneğin MongoDB veya PostgreSQL) ile entegre ederek, geçmiş verileri de sorgulayabileceğiniz bir dashboard yapısına dönüştürebilirsiniz.

Sorumluluk Reddi: Bu kod örnekleri eğitim amaçlıdır. Ticari projelerinizde güvenlik katmanlarını (Auth, Rate Limiting, Input Validation) profesyonel standartlarda yapılandırmanız gerekmektedir.

Bu yazıya tepkinizi paylaşın:
Deniz Aydın

On yıldır pratik yaşam çözümleri üzerine içerik üretiyorum. Okuyucuların karmaşık sorunlarını en sade ve uygulanabilir adımlarla çözmelerine yardımcı oluyorum.

Yorumlar (0)

Yorum Yaz