Kolme rakennuspalikkaa, yksi tavoite
Pinnan alla Timmy on rakennettu varsin käytännöllisesti: Flutter sovellukseen, WebRTC reaaliaikaiseen ääneen ja videoon sekä Firebase yhteyden koordinointiin. En halunnut rakentaa valtavaa alustaa, joka reitittää kaiken pilven kautta. Jokaisen osan pitäisi tietää mahdollisimman vähän ja silti toimia luotettavasti muiden kanssa.
WebRTC: suora yhteys, oletuksena salattu
WebRTC (Web Real-Time Communication) välittää äänen ja videon vauva- ja vanhempilaitteen välillä. Parhaassa tapauksessa data kulkee suoraan kahden laitteen välillä, vertaisverkossa ilman välissä olevaa mediapalvelinta.
Jokainen WebRTC-yhteys käyttää oletuksena DTLS-SRTP:tä. Vaikka joku kaappaisi verkkopaketteja, hän ei saa niistä luettavaa ääntä tai videota. Salaus on osa protokollaa, eikä sitä voi vain kytkeä pois päältä WebRTC:ssä.
Tämä oli minulle tärkeää: lastenhuoneen media ei kuulu palvelimelleni. Se pysyy laitteidesi välillä.
Signalointi Firebase Firestoren kautta
Ennen kuin WebRTC voi käynnistyä, laitteiden täytyy löytää toisensa ja sopia, miten ne voivat muodostaa yhteyden. Tätä osuutta kutsutaan nimellä signalointi. Timmy käyttää siihen Googlen pilvitietokantaa Firebase Firestorea.
Vain teknisiä yhteystietoja vaihdetaan:
- SDP-tarjoukset ja -vastaukset: Kuvaavat laitteiden ominaisuudet (tuetut koodekit, tarkkuudet jne.).
- ICE-ehdokkaat: Mahdolliset verkkoreitit, joiden kautta laitteet tavoittavat toisensa.
Ääni ja video eivät päädy Firebaseen. Firestore välittää vain tekniset yhteystiedot. Timmy salaa myös tämän signalointikerroksen, joten Firestoresta ei tule SDP- ja ICE-tietojen selväkielistä kohtauspaikkaa.
TURN-palvelimet: kun suora reitti ei toimi
Jotkin verkot estävät suorat yhteydet, esimerkiksi tiukat palomuurit tai tietyt mobiilioperaattorit. Silloin WebRTC tarvitsee TURN-välityksen (Traversal Using Relays around NAT).
Timmy kokeilee ensin paikallista TURN-palvelinta ja käyttää Cloudflarea varavaihtoehtona, jos paikallinen välityspalvelin ei ole käytettävissä tai on ylikuormittunut. Välityspalvelin välittää salatut paketit. Se ei saa äänen tai videon avaimia; WebRTC-salaus säilyy ennallaan.
TURN-tunnukset tulevat Firebase Cloud Functionista ja ovat voimassa vain 24 tuntia. Pysyvät tunnukset itkuhälytinsovelluksessa olisivat minusta liian riskialttiita.
Nearby Connections: laitteet löytävät toisensa automaattisesti
Jotta vauva- ja vanhemman laitteen käyttöönotto olisi mahdollisimman vaivatonta, Timmy käyttää Nearby Connectionsia. Google tarjoaa tämän löytämiskerroksen Bluetoothin ja WiFin kautta.
Automaattinen paritus Timmyssä toimii ilman manuaalista koodin syöttämistä: laitteet löytävät toisensa ja saman kohtaamispaikan avaintenvaihtoa varten. Jos se ei onnistu, voit kirjoittaa 4-merkkisen koodin. Parituskoodi ei koskaan poistu laitteelta; Firestore näkee asiakirjatunnisteena vain kryptografisen tiivisteen (SHA-256).
Anonyymi tunnistautuminen
Timmy käyttää Firebase Anonymous Authenticationia. Ensimmäisellä käynnistyskerralla jokainen laite saa väliaikaisen, anonyymin tunnuksen. Ei ole tiliä, sähköpostiosoitetta eikä salasanaa. Tunnus on olemassa vain Firestore-sääntöjen valvomiseksi: vain tunnistautuneet laitteet voivat lukea tai kirjoittaa istuntotietoja.
Arkkitehtuuri: kuka lähettää, kuka vastaanottaa
Timmyssä on kaksi tilaa:
- Vauvatila (lähettäjä): Laite ottaa äänen mikrofonista ja lähettää sen vanhemman laitteeseen WebRTC:n kautta. Halutessasi voit ottaa kameran käyttöön; silloin myös video lähetetään suoraan.
- Vanhemman tila (vastaanottaja): Laite vastaanottaa äänen ja videon, näyttää kamerakuvan ja tarjoaa push-to-talk-toiminnon lyhyitä ääniviestejä varten vauvalaitteeseen.
Push-to-talkin sekä kameran päälle- ja poiskytkennän kaltaiset ohjaustoiminnot käyttävät DataChannelia, toista WebRTC-kanavaa, joka lähettää pieniä salattuja viestejä suoraan laitteiden välillä.
Miksi Flutter?
Flutter on Googlen kehys useille alustoille tehtäville sovelluksille. Timmyssä se tarkoittaa, että voin kirjoittaa suuren osan logiikasta kerran ja käyttää sitä Androidilla ja iOS:llä. Timmy on saatavilla Androidille, ja iOS-versio on lähellä julkaisua. Vähemmän päällekkäistä koodia tarkoittaa vähemmän paikkoja, joihin virheitä voi hiipiä.
Yhteenveto
Tekninen periaate on yksinkertainen: Timmy saa käsitellä vain dataa, jota se oikeasti tarvitsee. WebRTC suojaa median, Firebase koordinoi yhteyden muodostamisen, TURN näkee vain salatut paketit ja Nearby Connections tekee parituksesta sujuvampaa.
Hyvä tekniikka sulautuu vähän osaksi arkea. Se toimii muuttamatta lastenhuonetta pilviprojektiksi.