Flutter projelerinde Socket.IO Kullanımı

Muhammed Almaz
Neyasis Technology

--

Ne Öğrenmeyi Hedefliyoruz?

Socket.IO kütüphanesini Flutter projelerinde kullanmayı ve basit bir şekilde video stream yapmayı hedefliyoruz. Bu işlemler için Web Real-Time Communication (WebRTC) mevcut fakat biz profesyonel bir video stream veya video call yapmayacağız. Bizim buradaki hedefimiz Socket.IO ile Flutter bağlantısı yapabilmek ve bu süreçleri yönetebilmektir. Bunun için de iki client arasındaki kamera görüntüsünü birbirleri arasında aktarabilmektir.

Kullanılacak Kütüphane, Framework ve Diller

JavaScript: Node.JS (Express.JS, Socket.IO)
Dart: Flutter (socket_io_client)

Başlamadan Önce

Başlamadan önce bilgisayarınızda Node (12+) uygulamasının yüklü olduğundan emin olunuz. Bilgisayarınızda şayet Node uygulaması yüklü değilse buradan Node uygulamasını indirebilirsiniz.

WebSocket nedir? Ne işe yarar? Ne amaç ile kullanılır?

WebSocket TCP veya UDP bağlantısı üzerinden çift yönlü haberleşme sağlayan protokoldür. TCP Socket ve UDP Socket arasında birtakım farklar bulunur fakat bu farkları sizlerle daha sonraki makalelerimizde ele alacağız. Bazı yapılarda server tarafından anlık olarak veri almamız gerekir. Örneğin kur bilgisi, kurye lokasyonları, son kullanıcının çevrimiçi/çevrimdışı durumu vb. bilgilerinden anlık olarak haberdar olmak isteriz. Bu durumda bir WebSocket bağlantısı oluşturup ilgili verinin güncellenmesi durumunda dinleyici clientlara veriyi gönderir. WebSocket yapısının bir diğer özelliği ise server istediği zaman istediği veriyi client tarafından alabilir. Haberleşmeler çift yönlü olduğundan iki cihaz birbirleriyle anlık veri paylaşımında bulunabilir. Bilindiği üzere Restfull API tek yönlü haberleşme sistemidir. API yapılarında sadece clientdan servera veri gönderilebilir. Socketlerin kullanıldığı yaygın uygulamalar canlı yayın, mesajlaşma, navigasyon ve analiz uygulamalarıdır. Bunun yanı sıra online oyunların tümünde socket kullanılır.

Haydi server-side kodlarımızı yazalım.

Öncelikle Server Side kodlarımızı yazmaya başlayalım. Boş bir dosya içerisinde aşağıdaki kodu çalıştırarak package.json dosyamızı oluşturalım.

npm install

Daha sonrasında express ve socket.io kütüphanelerini indirip kodlamaya geçelim.

npm install express socket.io

Socket Register
Son kullanıcının kim olduğunu sunucu tarafında bilmemiz için bir kimlik belirlemeliyiz. Bu kimlik ataması genellikle socket connection esnasında bir token aracılığıyla yapılır. Fakat bizim herhangi bir token altyapımız olmadığı için basit bir register işlemi ile son kullanıcımızın kimliğini belirleyeceğiz.

Token alt yapısını kullanmak isteyenler için de kısaca bir örnek yapalım. Connection callback yapısı socket bağlantısı gerçekleştiğinde bize bir listener sağlar. Bu listener sayesinde socket bağlantısı gerçekleştiği anda direkt kimlik sorgulanır. Kimlik sorgusu başarısız olduğu durumda socket bağlantısını kapatırız.

Get User List
Get User List, son kullanıcının aramak istediği kişilerin listesini çekebileceği bir servistir diyebiliriz. Yapılmak istenilen iş, socket bağlantısı gerçekleştiren kişilerin listesini alabilmektir. Burada bulunan filtreleme yapısı çok basit düzeyde bir filtreleme yapısına sahiptir. Tek satırda işi halletmek isteyen kişiler lodash kütüphanesini kullanabilir. Ekstra kütüphane kullanmamak amacıyla dilin salt halini kullanmaya çalıştım. Burada filtreleme ihtiyacı duyduğumuz kısım socket bağlantısı yapmış fakat register olmamış kişileri eleme yapmak istediğimiz kısımdır. Bu istekte callback(Acknowledgment) yapılarına değinmek isterim. Socket ile bir istekte bulunduğunuzda aslında sunucunun attığınız o isteğe cevap vermesi mümkün. Bunu da Acknowledgment (Ack) methodları ile yapıyoruz. Normalde socket isteklerinde bir response bulunmaz. Attığınız istekler sunucuya ulaşır ve sunucu bu istekleri yorumlar. Bu durumda sunucudan cevap alabilmek için Ack veya Callback yapılarını kullanmamız gerekmektedir.

Stream Data
Bu bölüm X kullanıcısının Y kullanıcısına o anki kamera görüntüsünü gönderdiği bölümdür. Bu kamera görüntüsü byte array cinsinden olup client tarafında encode ve decode işlemine tabi tutulur. Bu metodda callback yapısını kullanmamızın sebebi image upload işlemi tamamlandığında son kullanıcıya haber vermek. Aksi takdirde herhangi bir t anındaki imge dosyası upload işlemini gerçekleştirmeden t+1 anındaki imge dosyası da upload olacağından bu kuyruk sonsuza kadar devam eder. Bu durumda istemeden sunucumuza saldırı yapmış oluruz. 😋😋😋

Diğer İstekler
Call User, Close Call ve Accept Call isteklerinin sadece ilgili kişiye haber verme görevini üstlendiği kısımlardır.

Haydi client-side kodlarımızı yazalım.

Flutter uygulamamızda kullanmış olduğumuz kütüphaneler socket_io_client, rxdart, uuid, fluttertoast, camera ve image kütüphaneleridir. Başlamadan önce Bloc mimarisine ek birtakım özellikler ekleyerek projemizi biraz daha generic hale getirmeye çalıştım. Bu konuda farklı bir makalede kullanmış olduğum boilerplate ve Bloc mimarisi hakkında detaylı bilgiye aşağıda bulunan github linkinden ulaşabilirsiniz.

Socket Initialize
Burada static bir metod kullanarak uygulama ilk açıldığında socket bağlantısı yapıp ilgili listener metodlarını tanımlıyoruz. Belirtilen initialize metodunu main.dart veya istenilen ekranda çağırabilirsiniz.

Send Data
Bu kısımda artık kameradan aldığımız görüntüleri sunucuya gönderip kameranın ulaşacağı kişiye sunucu tarafından iletilmesini sağlayacağız. İlk olarak burada image kütüphanesinin etkili rol aldığını görebiliriz. Kameradan almış olduğumuz image dosyasını byte dizisine çevirirken image kütüphanesinin metodlarını kullanıyor olacağız. Yazmış olduğumuz Worker bizlere kameradan almış olduğumuz görüntüyü sunucuya gönderiyor olacak. Buradaki mantık kısaca şu şekildedir; kameradan alınan görüntüyü sunucuya gönder, gönderilen görüntü sunucuya ulaştıysa hemen yeni bir görüntüyü gönder ve bu şekilde sonsuza kadar devam et. Burada kesme koşulumuz çağrının sonlandığı yani ilgili Widget’in kapandığı durumdur.

Diğer İstekler
Son kullanıcı tarafında bulunan Call User, Close Call ve Accept Call isteklerinin yorumlandığı kısımlardır.

Sonuç

Socket.IO ile gerçek zamanlı bir şekilde X kullanıcısının Y kullanıcısı arasındaki görüntü alışverişini sağladık. Socket.IO kütüphanesini Flutter projelerinde nasıl kullanabileceğimizi ve Ack (callback) yapılarının kullanımını öğrendik.

Uygulama Demo Görüntüsü

Server ve client kodlarına aşağıda bulunan github linkinden ulaşabilirsiniz.

--

--

Muhammed Almaz
Neyasis Technology

I work as a Staff Software Engineer at OMWO Technology.