Gereksinimler ve Ön Hazırlık
Websocket mimarisini Flutter projenize entegre etmeden önce geliştirme ortamınızın güncel olduğundan emin olmalısınız. 2026 yılı itibarıyla Flutter 3.x ve üzeri sürümlerde, null-safety (boş değer güvenliği) standartlarını tam olarak destekleyen kütüphaneler kullanacağız.
- Flutter SDK (3.24 veya üzeri önerilir)
- Dart 3.6+ sürümü
web_socket_channelpaketi (Resmi Flutter topluluk paketi)- Backend tarafında bir Websocket sunucusu (Node.js/Socket.io veya Go/Gorilla WebSocket)
Projenizin pubspec.yaml dosyasına gerekli bağımlılığı ekleyerek işe başlayın:
dependencies:
flutter:
sdk: flutter
web_socket_channel: ^3.0.0
Bağımlılığı ekledikten sonra terminalde flutter pub get komutunu çalıştırarak paketleri projenize dahil edin.
Websocket Bağlantısını Kurma ve Yönetme
Websocket bağlantısı kurmak, bir kanal (channel) oluşturmakla başlar. Bağlantının kopması durumunda yeniden bağlanma (reconnection) mekanizması, profesyonel bir uygulamanın olmazsa olmazıdır. Aşağıdaki örnekte, temel bir bağlantı sınıfı oluşturuyoruz.
import 'package:web_socket_channel/web_socket_channel.dart';
class SocketService {
late WebSocketChannel _channel;
void connect() {
_channel = WebSocketChannel.connect(
Uri.parse('wss://api.uygulamaniz.com/ws'),
);
}
void sendData(String message) {
_channel.sink.add(message);
}
void dispose() {
_channel.sink.close();
}
}
Yukarıdaki kod, wss:// protokolünü kullanarak güvenli bir bağlantı başlatır. sink nesnesi, sunucuya veri göndermek için kullanılırken, bağlantı kapatıldığında dispose metodu ile kaynakların serbest bırakılması bellek sızıntılarını önler.
Gerçek Zamanlı Veri Akışını Dinleme (Stream Dinleyicileri)
Sunucudan gelen verileri anlık olarak arayüzde göstermek için StreamBuilder widget'ı en verimli yöntemdir. Bu yöntem, verinin değiştiği her an arayüzün yeniden çizilmesini sağlar.
StreamBuilder(
stream: _channel.stream,
builder: (context, snapshot) {
if (snapshot.hasError) return Text('Hata oluştu');
if (!snapshot.hasData) return CircularProgressIndicator();
return Text('Gelen Veri: ${snapshot.data}');
},
)
Bu yapı, gelen her paketi otomatik olarak yakalar. snapshot.hasData kontrolü, bağlantı kurulduktan sonra gelen ilk ve sonraki tüm mesajları işlemek için kullanılır.
Websocket İletişim Yöntemlerinin Karşılaştırılması
Mobil uygulamalarda gerçek zamanlı veri akışı için kullanılan yöntemlerin avantaj ve dezavantajlarını aşağıda görebilirsiniz:
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Websocket | Çift yönlü, düşük gecikme | Sunucu tarafında yüksek kaynak tüketimi |
| HTTP Polling | Basit, her sunucu destekler | Yüksek gecikme, gereksiz trafik |
| gRPC Streaming | Verimli, tip güvenli | Mobil tarafta kurulumu karmaşık |
Güvenli Veri İletişimi ve Kimlik Doğrulama
Websocket bağlantıları, HTTP istekleri gibi standart header'lar taşımaz. Bu nedenle kimlik doğrulama işlemini bağlantı kurulurken (handshake aşamasında) veya bağlantı kurulduktan hemen sonra bir "auth" mesajı göndererek yapmalısınız.
// Bağlantı kurulduktan sonra token ile kimlik doğrulama
void authenticate(String token) {
_channel.sink.add('{"action": "auth", "token": "$token"}');
}
Güvenlik Uyarısı: Websocket üzerinden asla şifrelenmemiş (plain-text) hassas veri göndermeyin. Her zaman
wss://(Websocket Secure) protokolünü kullanın. Ayrıca, sunucu tarafında gelen mesajları mutlaka doğrulayın (sanitization) ve SQL Injection gibi saldırılara karşı parametreli sorgular kullanın.
İleri Düzey Hata Ayıklama ve Bağlantı İzleme
Gerçek zamanlı uygulamalarda en büyük sorun, bağlantının arka planda sessizce kopmasıdır. Bunu çözmek için "Heartbeat" (kalp atışı) mekanizması kurmalısınız. Belirli aralıklarla sunucuya küçük bir "ping" paketi gönderip "pong" cevabı beklemek, bağlantının canlılığını doğrular.
import 'dart:async';
Timer? _heartbeatTimer;
void startHeartbeat() {
_heartbeatTimer = Timer.periodic(Duration(seconds: 30), (timer) {
_channel.sink.add('ping');
});
}
Bu kod bloğu, bağlantının aktif kalmasını sağlar ve ağ kesintilerini anında tespit etmenize olanak tanır.
Sıkça Sorulan Sorular
Websocket bağlantısı neden sürekli kopuyor?
Genellikle mobil cihazların güç tasarrufu modu veya ağ geçidi (gateway) zaman aşımları nedeniyle bağlantı düşer. Heartbeat mekanizması kullanmak bu sorunu çözer.
JSON verilerini nasıl işlerim?
Gelen string veriyi dart:convert kütüphanesini kullanarak jsonDecode() ile bir Dart nesnesine dönüştürmeniz gerekir.
Websocket ile dosya gönderilebilir mi?
Teknik olarak evet, ancak büyük dosyalar için Websocket yerine HTTP multipart upload yöntemini kullanmanız daha verimlidir.
Sunucu tarafında hangi dili seçmeliyim?
Gerçek zamanlı uygulamalar için Node.js (Socket.io) veya Go (Gorilla) yüksek eşzamanlılık desteği sunduğu için en iyi tercihlerdir.
Bağlantı koparsa otomatik nasıl bağlanırım?
WebSocketChannel nesnesini bir try-catch bloğu içinde sarmalayarak, hata durumunda Future.delayed ile belirli aralıklarla tekrar connect() metodunu çağıran bir döngü kurabilirsiniz.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında (production) kullanmadan önce hata yönetimi, yük dengeleme (load balancing) ve veri şifreleme katmanlarını uygulamanızın özel ihtiyaçlarına göre yapılandırmanız gerekmektedir.
Websocket Performans Optimizasyonu ve Veri Serileştirme
Gerçek zamanlı uygulamalarda yüksek frekanslı veri akışı, mobil cihazların pil ömrünü ve işlemci performansını doğrudan etkiler. Özellikle binlerce mesajın saniyeler içinde işlendiği senaryolarda, veriyi işleme biçiminiz uygulamanın akıcılığını belirler.
Veri İşleme Maliyetini Düşürmek
JSON verilerini her seferinde jsonDecode() ile ayrıştırmak, büyük veri paketlerinde ciddi bir CPU yükü oluşturur. Bunun yerine compute fonksiyonunu kullanarak ayrıştırma işlemini ayrı bir izole (isolate) üzerinde gerçekleştirebilirsiniz.
import 'dart:convert';
import 'package:flutter/foundation.dart';
// Veriyi arka planda işlemek için yardımcı fonksiyon
Future parseJsonAsync(String data) async {
return compute(_decodeAndParse, data);
}
Map _decodeAndParse(String data) {
return jsonDecode(data);
}
Binary Veri Transferi (Protobuf Kullanımı)
Eğer çok yüksek veri trafiğine sahip bir uygulama geliştiriyorsanız, JSON yerine Protocol Buffers (Protobuf) kullanmak bant genişliğini ve işlemci kullanımını %70'e kadar azaltabilir. Protobuf, veriyi ikili (binary) formatta sıkıştırarak gönderdiği için metin tabanlı JSON'a göre çok daha hızlıdır.
Websocket Üzerinde Birim ve Entegrasyon Testleri
Websocket bağlantılarını test etmek, uygulamanın kararlılığı için kritiktir. Canlı bir sunucuya bağımlı kalmadan test yapabilmek için StreamController kullanarak sahte (mock) bir sunucu ortamı oluşturabilirsiniz.
Mock Sunucu ile Test Senaryosu
Aşağıdaki örnek, gerçek bir ağ bağlantısı kurmadan websocket akışını nasıl simüle edebileceğinizi gösterir:
import 'dart:async';
import 'package:test/test.dart';
void main() {
test('Websocket mesajı doğru işleniyor mu?', () async {
final controller = StreamController();
// Test verisini akışa ekle
controller.add('{"status": "success", "data": 100}');
final stream = controller.stream;
// Akıştan gelen ilk veriyi doğrula
expect(await stream.first, contains('success'));
await controller.close();
});
}
Test Stratejileri
- Bağlantı Kopma Testi: Sunucuyu manuel olarak kapatıp, uygulamanın tekrar bağlanma (reconnect) mantığının devreye girip girmediğini test edin.
- Paket Kaybı Simülasyonu: Ağ hızını kısıtlayarak (throttling) uygulamanın yüksek gecikme sürelerinde nasıl tepki verdiğini gözlemleyin.
- State Doğrulama: Websocket üzerinden gelen verinin, uygulama içindeki State (Bloc/Riverpod) yapısını doğru güncellediğinden emin olun.
İleri Düzey İpuçları: Heartbeat ve Keep-Alive
Birçok yük dengeleyici (load balancer), belirli bir süre veri akışı olmayan websocket bağlantılarını "ölü" kabul ederek sonlandırır. Bunu engellemek için sunucu ve istemci arasında periyodik olarak küçük "ping" paketleri göndermek en sağlıklı yöntemdir.
import 'dart:async';
void startHeartbeat(Function sendPing) {
// Her 30 saniyede bir ping göndererek bağlantıyı canlı tut
Timer.periodic(Duration(seconds: 30), (timer) {
sendPing('ping');
});
}
Bu mekanizma, özellikle mobil cihazların arka plana atıldığı veya ağ geçişlerinin (Wi-Fi'dan 4G'ye geçiş gibi) yaşandığı durumlarda bağlantının kopmadan devam etmesini sağlar.
Sonuç
Flutter ile Websocket entegrasyonu, modern mobil uygulamaların temel taşıdır. Bu rehberde; bağlantı kurma, stream yönetimi, güvenlik önlemleri ve bağlantı sürekliliği sağlayan kalp atışı mekanizmasını ele aldık. Bir sonraki adım olarak, uygulamanızda gelen verileri Bloc veya Riverpod gibi state management kütüphaneleriyle birleştirerek, veri akışını uygulama genelinde yönetmeyi deneyebilirsiniz.

Yorumlar (0)
Yorum Yaz