Gereksinimler ve Ön Hazırlık
Başarılı bir kurulum için sisteminizde PHP 8.2 veya üzeri, Composer paket yöneticisi ve Laravel 11.x sürümünün yüklü olması gerekmektedir. Gerçek zamanlı iletişim için Laravel Echo ve Pusher veya Redis tabanlı bir WebSocket sunucusu kullanacağız.
- PHP 8.2+: Modern sözdizimi ve performans iyileştirmeleri için zorunludur.
- Composer: Bağımlılık yönetimi için gereklidir.
- Laravel Echo: İstemci tarafında WebSocket olaylarını dinlemek için kullanılır.
- Pusher veya Reverb: WebSocket sunucusu olarak Laravel'in yerel çözümü olan Reverb, 2026 standartlarında en yüksek performansı sunar.
Veritabanı Yapılandırması ve Model Oluşturma
Sohbet sistemimizin temelini mesajların saklanacağı veritabanı oluşturur. Mesajların kimden geldiğini ve hangi yayına ait olduğunu takip etmek için bir tablo yapısına ihtiyacımız vardır. İlk adım olarak mesaj modelimizi ve migration dosyamızı oluşturalım.
php artisan make:model Message -m
Migration dosyasını açarak mesajlar tablosunun sütunlarını tanımlayalım. Güvenlik için kullanıcı kimliklerini ve mesaj içeriğini doğru veri tipleriyle saklamalıyız.
public function up(): void
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->text('content');
$table->string('stream_id');
$table->timestamps();
});
}
Bu yapı, mesajların hangi kullanıcıya ait olduğunu ve hangi canlı yayında paylaşıldığını takip etmemizi sağlar. onDelete('cascade') kuralı, kullanıcı silindiğinde mesajlarının da temizlenmesini sağlayarak veritabanı bütünlüğünü korur.
Event (Olay) Yapılandırması ile Mesaj Yayınlama
Laravel'de bir mesaj gönderildiğinde, bu mesajın diğer kullanıcılara anlık olarak iletilmesi için "Event" mekanizmasını kullanırız. MessageSent adında bir olay sınıfı oluşturarak WebSocket üzerinden veri gönderimini tetikleyeceğiz.
php artisan make:event MessageSent
Olay sınıfımızda ShouldBroadcast arayüzünü (interface) uygulamamız gerekir. Bu, Laravel'e bu olayın WebSocket üzerinden yayınlanması gerektiğini söyler.
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(public Message $message) {}
public function broadcastOn(): Channel
{
return new Channel('stream.' . $this->message->stream_id);
}
}
Burada broadcastOn metodu, mesajın hangi kanala gönderileceğini belirler. Kanal ismini dinamik yaparak her yayının kendi sohbet odasına sahip olmasını sağlıyoruz.
Backend Kontrolcüsü ve Güvenlik Önlemleri
Kullanıcı mesajı gönderdiğinde çalışacak olan kontrolcü (controller) mantığını yazalım. Burada XSS (Cross-Site Scripting) saldırılarını engellemek için gelen veriyi doğrulamak ve temizlemek hayati önem taşır.
public function store(Request $request)
{
$validated = $request->validate([
'content' => 'required|string|max:500',
'stream_id' => 'required|string'
]);
$message = auth()->user()->messages()->create($validated);
broadcast(new MessageSent($message))->toOthers();
return response()->json(['status' => 'Mesaj gönderildi']);
}
toOthers() metodu, mesajı gönderen kişi hariç kanaldaki diğer herkese mesajın iletilmesini sağlar. Bu, istemci tarafında mesajın iki kez görünmesini engeller.
Kritik Güvenlik Uyarısı: Kullanıcıdan gelen mesajları veritabanına kaydetmeden önce mutlaka doğrulayın. HTML etiketlerini temizlemek için strip_tags() veya benzeri kütüphaneler kullanarak XSS saldırılarına karşı önlem alın. Ayrıca, kullanıcıların yetkili olup olmadığını kontrol eden "Policy" sınıflarını kullanmayı ihmal etmeyin.
Frontend: Laravel Echo ile Canlı Dinleme
İstemci tarafında, JavaScript kullanarak WebSocket kanalına bağlanmamız ve gelen mesajları arayüze eklememiz gerekiyor. Vite ve Laravel Echo kullanarak bu işlemi gerçekleştirelim.
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
forceTLS: false
});
window.Echo.channel('stream.1')
.listen('MessageSent', (e) => {
const chatBox = document.getElementById('chat-box');
chatBox.innerHTML += `${e.message.content}`;
});
Bu kod bloğu, belirli bir yayın odasına (stream.1) abone olur ve MessageSent olayı tetiklendiğinde yeni mesajı DOM'a ekler.
Karşılaştırma: WebSocket Yöntemleri
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Reverb (Yerel) | Hızlı, yapılandırması kolay, ücretsiz. | Sunucu kaynaklarını tüketir. |
| Pusher (SaaS) | Bakım gerektirmez, ölçeklenebilir. | Ücretli planlar gerektirebilir. |
| Redis/Socket.io | Çok yüksek trafik için ideal. | Kurulumu daha karmaşıktır. |
Sıkça Sorulan Sorular
WebSocket bağlantısı neden başarısız oluyor?
Genellikle .env dosyasındaki VITE_REVERB_HOST veya port ayarlarının yanlış olmasından kaynaklanır. Sunucunuzda ilgili portun (genellikle 8080) güvenlik duvarı tarafından açık olduğundan emin olun.
Mesajlar neden veritabanına kaydedilmiyor?
Modelinizde $fillable dizisinin doğru tanımlandığından emin olun. Ayrıca, Controller içerisinde auth()->user() üzerinden atama yapıyorsanız, kullanıcının giriş yapmış olması şarttır.
Canlı sohbeti nasıl daha güvenli hale getiririm?
Kullanıcıların mesaj gönderim hızını sınırlamak için Laravel'in RateLimiting özelliğini kullanın. Bu, botların sohbeti spam mesajlarla doldurmasını engeller.
Mobil cihazlarda senkronizasyon sorunu olur mu?
WebSocket protokolü cihazdan bağımsız çalışır. Ancak mobil tarayıcılarda pil tasarrufu modu bağlantıyı koparabilir; bu durumda otomatik yeniden bağlanma (reconnect) mantığını Echo konfigürasyonuna eklemelisiniz.
Yayın odası başına kaç kullanıcı desteklenir?
Bu tamamen sunucunuzun RAM ve CPU kapasitesine bağlıdır. Reverb ile tek bir sunucuda binlerce eşzamanlı bağlantıyı yönetebilirsiniz.
Yasal Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce güvenlik açıklarını tarayın, veritabanı yedeklerini alın ve profesyonel bir güvenlik denetiminden geçirin. Yazılım hatalarından doğabilecek veri kayıplarından yazar sorumlu tutulamaz.
Canlı Sohbet Sistemlerinde Performans Optimizasyonu ve Ölçeklendirme
Canlı sohbet sistemleri, kullanıcı sayısı arttıkça sunucu kaynaklarını yoğun bir şekilde tüketmeye başlar. Özellikle anlık mesaj trafiğinin yüksek olduğu yayınlarda, sistemin darboğaz yaşamaması için bazı stratejik optimizasyonlar yapmanız gerekir.
Redis ile Kuyruk Yönetimi
Mesajların veritabanına yazılması sırasında oluşabilecek gecikmeleri önlemek için Laravel'in kuyruk (queue) sistemini kullanmalısınız. Mesajı doğrudan veritabanına kaydetmek yerine, bir iş (job) olarak kuyruğa atmak, kullanıcıya yanıtın çok daha hızlı dönmesini sağlar.
// App/Jobs/ProcessChatMessage.php
public function handle()
{
Message::create([
'user_id' => $this->data['user_id'],
'content' => $this->data['content'],
'room_id' => $this->data['room_id'],
]);
}
Veritabanı İndeksleme Stratejileri
Sohbet odalarındaki mesajlar zamanla milyonlara ulaşabilir. Sorgu performansını korumak için room_id ve created_at sütunlarına mutlaka bileşik indeks (composite index) eklemelisiniz. Bu, "en son mesajları getir" sorgularının milisaniyeler içinde çalışmasını sağlar.
// Migration dosyanızda
$table->index(['room_id', 'created_at']);
Canlı Sohbet İçin İleri Düzey Hata Ayıklama Teknikleri
WebSocket bağlantıları, geleneksel HTTP isteklerine göre hata ayıklaması daha zor süreçlerdir. Bağlantı kopmaları veya mesaj iletim hatalarını tespit etmek için aşağıdaki yöntemleri izleyebilirsiniz.
Echo Bağlantı Durumu İzleme
Kullanıcıların bağlantı durumunu takip etmek, sistemin kararlılığını artırır. Laravel Echo'nun sunduğu listen metodunu kullanarak bağlantı hatalarını konsola loglayabilirsiniz.
window.Echo.connector.pusher.connection.bind('error', (err) => {
console.error('WebSocket Bağlantı Hatası:', err);
// Burada kullanıcıya "Bağlantı koptu, tekrar deneniyor..." mesajı gösterebilirsiniz.
});
window.Echo.connector.pusher.connection.bind('state_change', (states) => {
console.log('Bağlantı Durumu Değişti:', states.current);
});
Mesaj Teslimat Doğrulaması
Kullanıcı mesajı gönderdiğinde, mesajın sunucuya ulaştığını onaylamak için bir "teslimat onayı" (acknowledgement) mekanizması kurabilirsiniz. Bu, özellikle zayıf internet bağlantısına sahip mobil kullanıcılar için kritik bir UX (Kullanıcı Deneyimi) iyileştirmesidir.
| Durum | Anlamı |
|---|---|
| Pending | Mesaj sunucuya gönderiliyor. |
| Sent | Mesaj sunucuya ulaştı. |
| Failed | Mesaj iletilemedi, tekrar denenmeli. |
Bu mekanizmayı uygulamak için frontend tarafında bir durum yönetimi kütüphanesi (Pinia veya Vuex gibi) kullanarak mesajın o anki durumunu takip etmeniz önerilir.
Sonuç
Laravel ile dinamik bir yayın içi canlı sohbet sistemi kurmak, doğru araçlar ve yöntemler kullanıldığında oldukça verimli bir süreçtir. Reverb gibi modern WebSocket çözümleri, geliştiricilere düşük gecikmeli ve yüksek performanslı uygulamalar geliştirme imkanı tanır. Bu rehberde öğrendiğiniz adımları takip ederek uygulamanıza gerçek zamanlı etkileşim yeteneği kazandırabilirsiniz.
Bir sonraki adım olarak, bu sohbet sistemine "yazıyor..." göstergesi eklemeyi veya mesajlara emoji desteği getirmeyi deneyebilirsiniz. Laravel'in sunduğu esnek yapı sayesinde bu geliştirmeleri mevcut mimarinize kolayca entegre edebilirsiniz.


Yorumlar (0)
Yorum Yaz