WebRTC Nedir ve Kotlin’de Huawei Cloud DB ile Nasıl Kullanılır?

Caner Türe
Huawei Developers - Türkiye
8 min readJun 6, 2022

Giriş

Herkese selamlar, bu yazımda WebRTC’yi ve Kotlin’de Huawei Cloud DB’yi kullanarak bir WebRTC projesinde görüntülü ve sesli görüşme için bağlantıyı nasıl kurabileceğinizi anlatacağım.

Okurken karşılacağımız bazı kısaltmaların açılımları ve anlamları;
WebRTC - Web Base Real Time Communication - Web Tabanlı Gerçek Zamanlı İletişim
P2P - Peer to Peer - Eşler Arası Bağlantı
STUN -
Session Traversal Utilities for NAT - NAT için Oturum Geçişi Yardımcı Araçları
NAT -
Network Address Translation - Ağ Adresi Çevirisi
TURN -
Traversal Using Relays around NAT - NAT Çevresinde Yedekler Kullanarak Geçiş
SDP -
Session Description Protocol - Oturum Açıklama Protokolü
ICE - Interactive Connectivity Establishment - Etkileşimli Bağlantı Kurulumu

WebRTC Nedir?

Sesli, görüntülü ve data paylaşımlı görüşmeler birbirine bağlı iki istemci arasında medya akışı sağlanarak yapılır. Bu sebeple, bir istemciden başka bir istemciye medya akışı yapabilecek ve bu medyalarla P2P bir bağlantı kuracak bir yapıya ihtiyacımız var.

İşte bu bağlantının kurulması için WebRTC kütüphanesini kullanıyoruz.

WebRTC, tarayıcılara ve mobil uygulamalara API’ler aracılığıyla RTC özelliği sağlayan ücretsiz, açık kaynak kodlu bir kütüphanedir. WebRTC bileşenleri bu medya akışını en iyi şekilde sağlayacak şekilde optimize edilmiştir.

Ancak WebRTC tek başına yeterli olmayacak. Yapmamız gereken başka işlemler de var 👇

  • Sinyalleşme (Signaling)
  • STUN Server
  • TURN Server

Neden Cloud DB Kullanıyoruz?

Cloud DB, veri kullanılabilirliğini, güvenilirliğini, tutarlılığını ve güvenliğini sağlamanın yanı sıra cihaz ve bulut arasında sorunsuz veri senkronizasyonu sağlar ve çevrimdışı uygulama işlemlerini destekleyerek geliştiricilerin cihaz-bulut ve çoklu cihaz uygulamalarını hızla geliştirmesine yardımcı olur.

Bir görüşmenin başlatılması için doğru medya akışının sağlanması gerektiğinden bahsetmiştik. Bu medya akışının gerçekleşmesi için SDP ve ICE Candidate’lerin başarılı bir şekilde tutulması, aktarımlarının hızlı, eksiksiz bir biçimde sağlanması gerek. Bu sebeple Cloud DB bizim için bu noktada güzel bir seçenek oluyor.

SDP Nedir?

İçerisinde IP, port, ses ve görüntü kodekleri barındıran ve bu verileri JSON’a benzer bir yapıyla bastırıp sunucu aracılığıyla iki istemci arası bağlantının kurulması için kullandığımız veri paketidir.

Aşağıdaki veriler bir Offer SDP’ye ait. Burada bulunan yapıların anlamları şu şekilde;

  • v — Protokol versiyonu
  • o — Oturum kimliği
  • s — Oturum adı
  • t — Oturum süresi
  • a — Oturuma ait sıfır veya daha fazla özellik
  • m — Medya türü ve iletim adresi
  • c — Bağlantı bilgisi
Offer SDP Örneği

Sinyalleşme Nedir?

İki istemci arasında bir çağrı kurmak için, her iki istemci de medya hakkında veriler, mesajlar ve metadata göndererek birbirleriyle uyum sağlamalıdır.

Sinyalleşme bu iki istemcinin görüşme için birbirine bağlanmak istediğini, verileri nereye göndereceğini ve nereden alacağını takip etmek için kullanılır. Bu veriler IP, port, ses ve görüntü kodekleri içeren SDP yapılarını barındırır ve iki istemci arasında iletişim kurulmasını sağlar.

Sinyalleşme Offer/Answer mantığında hareket eder. Bu Offer ve Answer SDP’leri WebRTC tarafından üretilir ve iki istemci arasındaki bağlantı için kullanılır.

WebRTC tüm teknolojiler ile uyumlu olmak, sinyalleşme işlemlerini içerisinde barındırarak karmaşıklığı yaratmamak ve kullanıcıyı belirli bir teknolojiye zorlamamak için herhangi bir protokol tanımlamıyor. Bu sayede sinyalleşme için kullanacağımız sunucuyu kendimiz geliştirebilir veya hali hazırda var olan yapıları kullanabiliriz.

İşte tam bu noktada sinyalleşme işlemi için Cloud DB’yi kullanacağız 🥳

Şimdi kısaca bu sinyalleşme süreci nasıl işliyor bir görelim.

Sinyalleşme Süreci
  1. Aramayı başlatan istemci WebRTC kütüphanesi ile Offer SDP üretir.
  2. Offer SDP sinyalleşme işlemi için kullanılan sunucuya iletilir ve sunucu, bu gönderilen Offer SDP’yi aranan istemciye iletir.
  3. Offer SDP’yi sunucudan alan taraf bu SDP’yi WebRTC kütüphanesine aktarır ve WebRTC tarafından Answer SDP üretilir.
  4. Answer SDP sinyalleşme işlemi için kullanılan sunucuya iletilir ve sunucu, Answer SDP’yi arayan istemciye gönderir.
  5. Arayan taraf, gelen bu SDP’yi WebRTC kütüphanesine aktarır.
  6. Offer/Answer SDP işlemleri tamamlanır ve eşler arasındaki bağlantı kurulduktan sonra peer-to-peer olarak medya aktarımı sağlanır.

P2P Bağlantı

Sinyal iletimleri gerçekleştikten sonra, her iki istemciyi de eşler arası yani peer to peer olarak bağlamamız gerekiyor. Ve bağlanmak için her iki istemcinin de public IP adresine sahip olmalı, NAT’lar üzerinden bu adresleri öğrenmeli ve bu adresleri SDP’ler içerisinde taşımalıyız.

P2P Çalışma Yapısı

NAT

Cihazımıza public IP adresi tanımlamak için kullanılır. Bir yönlendiricinin (router) bir public IP adresi olacak ve yönlendiriciye bağlı her cihazın da birer private IP adresi olacaktır. İsteğimiz, cihazın private IP’si kullanılarak benzersiz bir port noktasıyla yönlendiricinin public IP’sine çevrilmesidir. Böylece, her cihaz için benzersiz bir public IP’ye ihtiyacınız olmaz ama yine de bu durumda tüm dünyadan erişilebilir olmaktan kurtulamıyoruz :)

STUN Sunucusu

NAT iyi güzel bir iş yapıyor ama peer to peer bağlantı kurmak için genelde kullanamadığımız bir private IP adresi sağlar. Fakat WebRTC için public IP adresine ihtiyacımız var. Bu nedenle, public IP adresini almak için STUN Sunucusunu kullanıyoruz.

STUN sunucusu olarak Google tarafından sağlanan veya erişime açık diğer sunucular kullanılabilir. Buradaki süreç, istemcinin STUN’ı tetiklemesi ve sonucunda public IP ve port bilgilerini alması üzerinedir. Sonrasında bildiğimiz üzere bu veriler ile sinyalleşme süreci devam ettirilir.

STUN Sunucuları Çalışma Yapısı

TURN Sunucusu

STUN sunucularının da az bir ihtimal de olsa başarısız olduğu durumlar söz konusu olabilir. Bu gibi durumlar için kullanılan diğer bir yapı da TURN sunucularıdır. Bu sunucu ile birlikte görüşmelerin tamamı başarıyla sonuçlanır.

Fakat buradaki süreç, ses veya görüntü kodeklerinin iletiminin sunucu üzerinden gerçekleştirilmesinden ve dolayısıyla da sunucunun bant genişliğinin kullanılmasından dolayı maliyetli olabilir.

TURN Sunucuları Çalışma Yapısı

ICE

Son olarak öğreneceğimiz terim ICE. WebRTC’nin yukarıda gördüğümüz P2P, STUN ve TURN seçeneklerinden hangisine yönelmesi gerektiğini otomatikleştirmek adına ICE kavramı ortaya çıkarılmıştır. ICE, yukarıdaki bağlantı türlerini dener ve ilk başarılı bağlantıyı kurduğu anda sistemi kurar. Bunun sağlanması için de WebRTC’ye ICE sunucu bilgilerini iletip doğru bağlantıyı seçmesini bekleriz.

Şimdi gelelim WebRTC’yi Cloud DB ile birlikte nasıl kullanacağımıza. Adım adım ilerliyoruz.

WebRTC Kütüphanesi Entegrasyonu

WebRTC’yi projemize dahil etmek oldukça basit. Aşağıdaki satırı gradle’a eklememiz ve projemizi sync etmemiz yeterli.

implementation 'org.webrtc:google-webrtc:1.0.30039'

HMS Core Entegrasyonu

Başlangıç olarak bir Huawei Developer hesabı açarak projemizi App Gallery Connect içerisinde oluşturmamız gerekiyor. Bu adımı aşağıdaki yazıyı takip ederek kolayca tamamlayabilirsiniz.

Android | Uygulamalarınıza Huawei HMS Core Entegre Edin | by Ibrahim R. Serpici | Huawei Developers — Türkiye | Medium

Cloud DB Entegrasyonu ve Kullanımı

Bu kısımda Cloud DB Dokümantasyonu ve Cloud DB Codelab’ini takip edebilirsiniz.

Ardından Cloud DB içerisinde kullandığımız Object Type’ları yani tabloları bir görelim.

Sdp (ObjectType)
Candidates (ObjectType)

Cloud DB ile SDP Sinyalleşme İşlemleri Nasıl Gerçekleştiriliyor?

Bu noktada Cloud DB kullanarak bu veri alışverişini nasıl kontrol ediyoruz onu göreceğiz.

Yine adım adım ilerleyelim. Yukarılarda “Sinyalleşme Nedir?” kısmında 8 adımlı bir süreç görmüştük. Gelin onu simüle edelim birlikte.

1–2. Offer SDP oluşturma - Offer SDP’yi sunucuya(Cloud DB) iletme

Yukarıdaki kodda WebRtcClient.kt dosyamızdaki call() fonksiyonunu görüyoruz. Burada yaptığımız işlem, peerConnection içerisindeki createOffer metodunu çalıştımak ve içerisine SdpObserver ve MediaConstraints yapılarını aktarmak. İçeride ise bu SdpObserver’dan dönen description ve type verilerini yani offer sdp verilerini, önce 8.satırdaki işlemle local olarak WebRTC’ye ekliyoruz ve sonrasında WebRtcClient.kt sınıfı oluşturulduğu anda random olarak değer atanan meetingID ile birlikte veritabanımıza aktarma işlemi gerçekleştiriyoruz.

3. Offer SDP’nin aranan tarafından alınıp WebRTC’ye aktarılması ve sonunda Answer SDP üretilmesi

Burası SDP için sinyalleşme ve buna bağlı callback işlemlerinin gerçekleştiği listenerımız. Şu anda veritabanında bir Offer SDP bulunuyor ve bu listener sürekli olarak yani canlı dinleme işlemi gerçekleştirdiğinden bu Offer SDP’yi algıladı ve 19.satırdaki scope a girdi. SignalingListener’daki onOfferReceived fonksiyonuna Offer SDP’den aldığı SessionDescription’ı yani arama tipini ve sdp bilgilerini aktardı.

4. Answer SDP sinyalleşme işlemi için kullanılan sunucuya iletilir ve sunucu, Answer SDP’yi arayan istemciye gönderir.

Aktarımdan sonra VoiceCallActivity.kt’de bulunan CallBack’e düştü ve burada aranan istemci, 2. satırda gelen Offer SDP’yi remote olarak aşağıdaki fonksiyon ile WebRTC’ye gönderdi.

Ardından 3.satırda Answer SDP oluşturma ve Cloud DB’ye gönderme adımına geçtik. Aynı call() fonksiyonunda olduğu gibi bu sefer peerConnection?.createAnswer ile bir cevap oluşturulur ve aktarım sağlanır.

5. Arayan taraf, Answer SDP’yi dinler ve geldiği anda WebRTC kütüphanesine aktarır.

Bu sefer arayan kişi SignalingClient içindeki listenerda 30.satırdaki koşula girer ve yukarıda gerçekleşen işlemler tekrarlanır. Bu sefer onAnswerReceived devreye girer ve sdp bilgileri ona gönderilir.

6. Offer/Answer SDP aktarım işlemleri tamamlanır ve bağlantı kurulduktan sonra medya aktarımları gerçekleşerek görüşme başlatılır.

onAnswerReceived dinlenerek Offer’da olduğu gibi burada da karşıdan gelen sdp bilgileri remote olarak WebRTC’ye aktarılır ve CallActivity içerisinde dinlenerek sol üstte bulunan süre başlatılır

ICE Candidates Aktarım Süreci

Şimdi de ICE Candidates yani ICE adaylarımızın (Yukarıda en uygun seçimi yapacağını bu sebeple tüm seçenekleri göndereceğimizi söylemiştik. O sebeple Candidate yani aday olarak isimlendiriliyor) sürecine bir bakalım. ICE adaylarımızın aktarım süreci SDP aktarımları ile paralel ilerliyor bu arada. Yani aslında hem SDP hem ICE Candidate süreçleri tamamlandığında başarılı iletişim kuruluyor. Ama karışmaması adına burada ayrı anlatmak istedim.

Buradaki callback peerConnection?.createOffer ve createAnswer metotları çalıştığı anda tetikleniyor ve bahsettimiz ICE’lar üretilmeye başlanıyor.

Ice Candidate’lerin Cloud DB ve WebRTC aktarımı için tetiklenmesi
Ice Candidate’lerin Cloud DB’ye aktarımı
Ice Candidate’lerin WebRTC’ye aktarımı

Üretilen her ICE adayına ait bilgiler SignalingClient ve WebRTC’deki bu fonksiyonlara gönderiliyor ve Cloud DB içerisindeki Candidates tablosuna yine meetingID ile yazdırılıp, WebRTC’ye de gönderiliyor.

Buradaki verilerin anlamları şu şekilde;
serverUrl — Bağlantının kurulacağı server adresi
sdpMid — Audio, Video, Data olarak 3 şekilde yazdırılır. Hangisini üretmesini istediğiniz uygulamanızın ihtiyacına kalmış.
sdpMidLineIndex — 0,1,2 olarak 3 şekilde yazdırılır.
0-Audio
1-Video
2-Data anlamlarına gelmektedir.
sdp — Bunu zaten yukarılarda da çokça açıkladık. Bu tüm bilgilerin JSON’a benzer bir yapıda gösterim hali.
type — Arama tipini ifade eder. offerCandidate, answerCandidate olarak 2 farklı ifadesi vardır. SDP aktarım sürecine göre bu type da değişir ve ona göre yazdırılır.

Burası aynı SDP’de olduğu bu sefer ICE adaylarının tablosunu canlı olarak dinlediğimiz listener. Burada dinlediğimiz verinin tipine göre offer veya answer ICE adaylarını WebRTC’ye aktarma işlemi için onIceCandidateReceived tetikleniyor.

Tetiklenen bu CallBack içerisinde dönen ICE adayı verileri addIceCandidate fonksiyonuna aktarılıyor.

Buraya gelen veriyi WebRTC’ye iletiyoruz her zaman olduğu gibi. Böylece WebRTC bizim için en uygun yolu seçerek bağlantıyı kuruyor.

Tabii ki burada anlatılan kısımlar 2 istemci arası bağlantıyı kurma işlemleri için gerekli aşamaları anlatmak içindi. Bunların ve diğer tüm yapıların proje içerisinde nasıl kullanıldığını görmek için projemi inceleyebilirsiniz 😀👇

Sonuç

Bu yazımda WebRTC’yi, Android Kotlin ve Huawei Cloud DB servisini kullanarak bir WebRTC projesinde görüntülü ve sesli olarak iletişim kurmak için bağlantıyı nasıl kurabileceğinizi olabildiğince kısa bir şekilde anlatmaya çalıştım. Umarım herkes için faydalı bir yazı olmuştur 😊

Referanslar

WebRTC

WebRTC API — Web APIs | MDN (mozilla.org)

Get Started with WebRTC — HTML5 Rocks

WebRTC 1.0: Real-Time Communication Between Browsers (w3.org)

--

--