Zorluk

Bir eğitim platformunda zamanında bildirimler kritik öneme sahiptir. Bir öğretmen yeni bir ödev yayınladığında öğrencilerin hemen haberdar olması gerekir. Bir öğrenci çalışmasını gönderdiğinde öğretmen anında bilgilendirilmelidir. Bir yönetici programı değiştirdiğinde etkilenen herkesin güncellemeyi gerçek zamanlı görmesi gerekir.

Orijinal bildirim sistemimiz yoklama tabanlıydı — istemci her 30 saniyede bir yeni bildirimleri kontrol ediyordu. Bu yaklaşımın üç büyük sorunu vardı: geciken bildirimler (30 saniyeye kadar), sürekli yoklamadan kaynaklanan sunucu kaynak israfı ve mobil cihazlarda düşük pil ömrü.

Mimari Genel Bakış

Sistemi sıfırdan aşağıdaki bileşenlerle WebSocket tabanlı bir mimari kullanarak yeniden inşa ettik:

  • WebSocket Gateway: Tüm bağlı istemcilerle kalıcı bağlantılar sürdüren Socket.io kullanan bir Node.js sunucusu.
  • Olay Yolu: Bildirim olaylarını birden fazla sunucu örneğine dağıtan Redis tabanlı bir yayınla/abone ol sistemi.
  • Bildirim Servisi: Yapılandırılabilir kurallara göre bildirimleri oluşturan, depolayan ve yönlendiren bir arka uç servisi.
  • Angular Signal Store: Bildirim durumunu yöneten Angular sinyallerini kullanan istemci tarafı reaktif bir mağaza.

WebSocket Katmanı

Her istemci giriş yaptığında bir WebSocket bağlantısı kurar. Bağlantı, REST API çağrıları için kullanılan aynı JWT token ile kimlik doğrulaması yapılır. Socket.io odalarını kullanarak bağlantıları kiracıya (okul) ve kullanıcı rolüne göre gruplandırıyoruz, böylece verimli yayın yapabiliyoruz.

Ölçeklendirme

Binlerce eşzamanlı bağlantıyla tek bir WebSocket sunucusu yeterli değildir. Olayları birden fazla sunucu örneği arasında senkronize etmek için Socket.io için Redis adaptörü kullanıyoruz. Bir bildirim yayınlandığında Redis, hedef istemcinin bağlantısını tutan doğru sunucu örneğine ulaşmasını sağlar.

Angular Sinyalleri ile İstemci Tarafı

Frontend'de bildirim durumunu yönetmek için Angular'ın sinyal tabanlı reaktivitesini kullanıyoruz. Bir WebSocket mesajı geldiğinde sinyal mağazasını günceller ve bildirim verilerini tüketen tüm bileşenlerde otomatik olarak UI güncellemelerini tetikler.

Çevrimdışı Destek

Tüm kullanıcılar her zaman bağlı değildir. Çevrimdışı bir kullanıcı için bildirim oluşturulduğunda veritabanında saklanır ve teslim edilmemiş olarak işaretlenir. Kullanıcı yeniden bağlandığında sistem bekleyen tüm bildirimleri öncelik ve zaman damgasına göre sıralanmış tek bir toplu iş halinde gönderir.

Yeni sistem ortalama 100ms'nin altında bildirim sunarken, eski yoklama yaklaşımıyla 30 saniyeye kadar çıkıyordu — 300 kat iyileştirme.