Gereksinimler ve Ön Hazırlık
İleri düzey bir Websocket uygulaması geliştirmek için sadece bir kütüphane yeterli değildir; doğru bir mimari altyapıya ihtiyacınız vardır. 2026 standartlarına uygun olarak, projenizde aşağıdaki araçların ve sürümlerin kurulu olduğundan emin olmalısınız.
- Flutter SDK: 3.24 veya üzeri (Null Safety zorunludur).
- web_socket_channel: Resmi Flutter Websocket paketi.
- riverpod veya bloc: Durum yönetimi için (bu rehberde mimari bağımsız yapı kullanılacaktır).
- json_serializable: Veri modellerini güvenli şekilde dönüştürmek için.
Geliştirme ortamınızda pubspec.yaml dosyanıza gerekli bağımlılıkları ekleyerek başlayın:
dependencies:
web_socket_channel: ^3.0.0
json_annotation: ^4.9.0
logger: ^2.4.0
Websocket Protokolü ve Flutter Mimari Seçimi
Websocket, istemci ve sunucu arasında kalıcı bir TCP bağlantısı kurar. HTTP'nin aksine, her istekte başlık (header) göndermek zorunda kalmazsınız. Bu, özellikle yüksek frekanslı veri güncellemelerinde bant genişliği tasarrufu sağlar. Flutter tarafında bu bağlantıyı "Singleton" bir servis yapısı içinde tutmak, uygulamanın her yerinden erişilebilir ve yönetilebilir olmasını sağlar.
Aşağıdaki örnek, bağlantıyı yöneten temel sınıf yapısını göstermektedir:
class WebSocketService {
late WebSocketChannel _channel;
void connect(String url) {
_channel = WebSocketChannel.connect(Uri.parse(url));
}
Stream get stream => _channel.stream;
void sendMessage(String message) {
_channel.sink.add(message);
}
void dispose() {
_channel.sink.close();
}
}
Adım Adım Bağlantı ve Hata Yönetimi
İleri düzey uygulamalarda bağlantının kopması kaçınılmazdır. Bu nedenle, otomatik yeniden bağlanma (auto-reconnect) mekanizması kurmak zorunludur. Bağlantı koptuğunda kullanıcıya bildirim göndermek ve arka planda bağlantıyı denemek, kullanıcı deneyimini doğrudan etkiler.
Aşağıdaki kod bloğu, bağlantı hatalarını yakalayan ve yeniden deneme mantığını içeren bir yapıdır:
void _connectWithRetry() {
try {
_channel = WebSocketChannel.connect(Uri.parse('wss://api.example.com'));
_channel.stream.listen(
(data) => _handleData(data),
onError: (error) => _reconnect(),
onDone: () => _reconnect(),
);
} catch (e) {
Future.delayed(Duration(seconds: 5), _connectWithRetry);
}
}
Veri Serileştirme ve Güvenlik
Websocket üzerinden gelen veriler genellikle JSON formatındadır. Ancak, ham JSON ile çalışmak tip güvenliğini (type-safety) bozar. json_serializable kullanarak gelen verileri Dart nesnelerine dönüştürmek, çalışma zamanı hatalarını minimuma indirir. Ayrıca, Websocket bağlantılarında "Man-in-the-Middle" saldırılarına karşı mutlaka WSS (Websocket Secure) protokolünü kullanmalısınız.
Kritik Uyarı: Üretim ortamında (production) asla düz WS protokolünü kullanmayın. Veri trafiğini şifrelemek için her zaman WSS kullanın ve bağlantı isteklerinde JWT (JSON Web Token) ile kimlik doğrulaması yapın.
Veri güvenliği için gelen mesajı doğrulayan bir yapı kurun:
factory DataModel.fromJson(Map json) {
return DataModel(
id: json['id'] as String,
value: json['value'] as double,
);
}
Websocket Yöntemlerinin Karşılaştırması
Projeniz için en uygun yöntemi seçerken aşağıdaki tabloyu referans alabilirsiniz:
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Raw WebSocket | Düşük gecikme, tam kontrol | Karmaşık hata yönetimi |
| Socket.io | Otomatik yeniden bağlanma | Daha büyük paket boyutu |
| SignalR | .NET entegrasyonu kolay | Bağımlılıklar artar |
Uygulama İçinde Gerçek Zamanlı Veri Güncelleme
Flutter'da StreamBuilder, Websocket'ten gelen verileri UI katmanına yansıtmak için en performanslı araçtır. Veri akışını dinlerken widget ağacını gereksiz yere yeniden oluşturmamak için StreamBuilder'ı doğru konumlandırmalısınız.
StreamBuilder(
stream: webSocketService.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text("Güncel Değer: ${snapshot.data}");
}
return CircularProgressIndicator();
},
)
Sıkça Sorulan Sorular
Websocket bağlantısı neden sürekli kopuyor?
Genellikle ağ kesintileri veya sunucu tarafındaki "idle timeout" (boşta kalma zaman aşımı) süresinden kaynaklanır. Sunucuya düzenli "ping/pong" paketleri göndererek bağlantıyı canlı tutmalısınız.
JSON verilerini nasıl daha hızlı işleyebilirim?
Büyük veri setleri için compute fonksiyonunu kullanarak JSON serileştirme işlemini ana iş parçacığı (main thread) dışında yapabilirsiniz.
Websocket yerine neden Firebase Realtime kullanmıyorum?
Firebase kolaydır ancak maliyetlidir ve veri yapısı üzerinde tam kontrol sağlamaz. Kendi Websocket altyapınız, daha düşük maliyet ve özelleştirilmiş protokoller sunar.
Bağlantı güvenliğini nasıl sağlarım?
Bağlantı kurulurken HTTP Header kısmına Authorization: Bearer {token} ekleyerek sunucu tarafında doğrulamayı zorunlu kılın.
Mobil cihazlarda pil tüketimini nasıl optimize ederim?
Uygulama arka plana geçtiğinde bağlantıyı kapatın ve uygulama ön plana geldiğinde tekrar açın. Sürekli açık bağlantı, pil ömrünü ciddi oranda azaltır.
Güvenlik Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Uygulamanızda kullanacağınız tüm veri trafiğinde şifreleme (TLS/SSL) standartlarını uyguladığınızdan ve kullanıcı verilerini korumak için gerekli güvenlik protokollerini (OWASP standartları gibi) takip ettiğinizden emin olun.
Websocket İletişiminde İleri Düzey Hata Ayıklama ve İzleme Stratejileri
Gerçek zamanlı uygulamalarda, bağlantı koptuğunda veya veri akışı durduğunda sorunun kaynağını tespit etmek oldukça zorlayıcı olabilir. Profesyonel bir geliştirici, sadece bağlantıyı kurmakla kalmamalı, aynı zamanda bağlantı yaşam döngüsünü izleyebilecek bir "gözlemci" mekanizması kurmalıdır.
İletişim Katmanı İçin Loglama ve İzleme
Websocket trafiğini izlemek için web_socket_channel paketinin sunduğu stream'leri dinleyen özel bir logger sınıfı oluşturmak, hata ayıklama sürecini %80 oranında hızlandırır. Aşağıdaki örnekte, gelen ve giden tüm paketleri zaman damgalarıyla kaydeden bir yapı bulunmaktadır:
class WebSocketLogger {
void logEvent(String eventType, dynamic data) {
final timestamp = DateTime.now().toIso8601String();
print('[$timestamp] [WS_EVENT: $eventType] -> Data: $data');
}
}
// Kullanım örneği:
final logger = WebSocketLogger();
channel.stream.listen(
(message) => logger.logEvent('INCOMING', message),
onError: (error) => logger.logEvent('ERROR', error),
onDone: () => logger.logEvent('CONNECTION', 'Closed'),
);
Network Trafiğini İncelemek İçin Araçlar
Mobil cihazlarda uygulama içi logların yanı sıra, dışarıdan paket analizi yapmak da kritiktir. Proxyman veya Charles Proxy gibi araçlar, Flutter uygulamanız ile sunucu arasındaki websocket handshake ve frame değişimlerini canlı olarak görmenizi sağlar. Özellikle SSL pinning kullanıyorsanız, bu araçları cihazınıza sertifika yükleyerek yapılandırmanız, şifreli verileri deşifre ederek incelemenize olanak tanır.
Ölçeklenebilir WebSocket Mimarisi: Load Balancer ve Sticky Sessions
Uygulamanız büyüdüğünde, tek bir sunucu tüm bağlantıları yönetemeyebilir. WebSocket bağlantıları "stateful" (durumlu) oldukları için, geleneksel HTTP yük dengeleyicilerinde sorun yaşanabilir. Bu durumun önüne geçmek için Sticky Sessions (Session Affinity) yapılandırması şarttır.
Nginx Üzerinde WebSocket Yapılandırması
Sunucu tarafında Nginx kullanıyorsanız, bağlantıların aynı sunucuya yönlendirilmesini sağlamak için aşağıdaki konfigürasyon bloğunu kullanmalısınız:
upstream websocket_servers {
ip_hash; # İstemci IP'sine göre aynı sunucuya yönlendirme
server 127.0.0.1:8080;
server 127.0.0.1:8081;
}
server {
location /ws {
proxy_pass http://websocket_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
}
}
Bağlantı Kopmalarında "Backoff" Algoritması
Bağlantı koptuğunda sürekli deneme yapmak (reconnect loop), sunucunuza gereksiz yük bindirir ve cihazın pilini tüketir. Bunun yerine Exponential Backoff (Üstel Geri Çekilme) algoritması kullanarak, her başarısız denemede bekleme süresini artırmalısınız.
int retryAttempt = 0;
Future connectWithBackoff() async {
try {
// Bağlantı denemesi...
retryAttempt = 0;
} catch (e) {
int delay = min(pow(2, retryAttempt).toInt(), 30); // Maksimum 30 saniye
await Future.delayed(Duration(seconds: delay));
retryAttempt++;
connectWithBackoff();
}
}
Bu yöntem, sunucunuzun yoğun olduğu anlarda uygulamanızın "self-healing" (kendi kendini iyileştirme) kapasitesini artırarak sistemin çökmesini engeller.
Sonuç
Flutter ile Websocket üzerinden gerçek zamanlı veri akışı sağlamak, uygulamanıza profesyonel bir hız ve etkileşim kazandırır. Bu rehberde; bağlantı yönetimi, hata toleransı, veri serileştirme ve performans optimizasyonu konularına odaklandık. Bir sonraki adım olarak, Websocket üzerinden gelen verileri yerel bir veritabanında (örneğin Hive veya Drift) önbelleğe alarak, internet kesintilerinde bile uygulamanın çevrimdışı çalışmasını sağlayan bir katman ekleyebilirsiniz.


Yorumlar (0)
Yorum Yaz