HTTP, WebSockets, WebRTC και Push Notifications: Πώς επικοινωνούν πραγματικά οι εφαρμογές στο Internet;

Από ένα απλό GET request μέχρι μια βιντεοκλήση μεταξύ δύο browsers, ας δούμε πώς μεταφέρονται τα δεδομένα στο Internet, ποιος είναι ο ρόλος του TCP και του UDP και πότε χρειαζόμαστε τεχνολογίες όπως SSE, WebSockets, STUN και TURN.

Efthimios Theotokatos 11′ ανάγνωση

HTTP, WebSockets, WebRTC και Push Notifications: Πώς επικοινωνούν πραγματικά οι εφαρμογές στο Internet;

Κάθε φορά που ανοίγουμε μια ιστοσελίδα, στέλνουμε ένα μήνυμα ή συμμετέχουμε σε μια βιντεοκλήση, οι συσκευές μας ανταλλάσσουν δεδομένα μέσω δικτύου.

Αυτό που αλλάζει είναι ο τρόπος με τον οποίο πραγματοποιείται η επικοινωνία.

Μια ιστοσελίδα μπορεί να ζητήσει πληροφορίες από έναν web server και να περιμένει την απάντησή του. Μια εφαρμογή συνομιλίας μπορεί να διατηρεί ανοιχτή μια σύνδεση για να λαμβάνει μηνύματα αμέσως. Μια εφαρμογή βιντεοκλήσεων μπορεί να συνδέει δύο χρήστες απευθείας μεταξύ τους.

Πίσω από αυτές τις λειτουργίες υπάρχουν διαφορετικά πρωτόκολλα και τεχνολογίες. Ας τα εξετάσουμε από την αρχή.

1. HTTP: Ο browser ζητά, ο server απαντά

Το HTTP (Hypertext Transfer Protocol) είναι το πρωτόκολλο που χρησιμοποιείται για την ανταλλαγή πληροφοριών μεταξύ web clients και servers.

Για παράδειγμα, όταν επισκεπτόμαστε μια ιστοσελίδα, ο browser στέλνει ένα HTTP request στον server.

Ο server επεξεργάζεται το αίτημα και επιστρέφει ένα HTTP response.

Η διαδικασία είναι απλή:

Browser → HTTP Request → Web Server → HTTP Response → Browser

Τα HTTP requests διαθέτουν διαφορετικές μεθόδους, ανάλογα με την ενέργεια που θέλουμε να πραγματοποιήσουμε.

HTTP Method

Λειτουργία

GET

Ανάκτηση δεδομένων

POST

Υποβολή δεδομένων για επεξεργασία ή δημιουργία πόρου

PUT

Αντικατάσταση πόρου

PATCH

Μερική τροποποίηση πόρου

DELETE

Διαγραφή πόρου

HEAD

Ανάκτηση των headers χωρίς το response body

OPTIONS

Ανακάλυψη διαθέσιμων δυνατοτήτων επικοινωνίας

Ας υποθέσουμε ότι μια εφαρμογή θέλει να εμφανίσει προϊόντα από μια βάση δεδομένων.

Η JavaScript μπορεί να εκτελέσει:

const response = await fetch('/api/products');

const products = await response.json();

Ο server επιστρέφει τα δεδομένα και ο browser τα εμφανίζει.

Τι είναι το HTTP Response;

Η απάντηση ενός HTTP server περιλαμβάνει έναν κωδικό κατάστασης, γνωστό ως HTTP Status Code.

Για παράδειγμα:

200 OK: Το αίτημα ολοκληρώθηκε επιτυχώς.

201 Created: Δημιουργήθηκε ένας νέος πόρος.

301 Moved Permanently: Ο πόρος έχει μεταφερθεί μόνιμα.

404 Not Found: Ο ζητούμενος πόρος δεν βρέθηκε.

500 Internal Server Error: Παρουσιάστηκε εσωτερικό σφάλμα στον server.

Ο browser χρησιμοποιεί την απάντηση για να αποφασίσει πώς θα συνεχίσει.

Το HTTP, όμως, δεν περιορίζεται στην απλή φόρτωση ιστοσελίδων. Αποτελεί επίσης τη βάση για πολλές τεχνολογίες συνεχούς ενημέρωσης.

2. Polling: Όταν ο browser ρωτά συνεχώς τον server

Ας φανταστούμε μια εφαρμογή που εμφανίζει την πρόοδο ενός web crawler.

Ο crawler επισκέπτεται εκατοντάδες ιστοσελίδες και ο χρήστης θέλει να γνωρίζει πόσες έχουν ολοκληρωθεί.

Μια απλή λύση είναι το polling.

Ο browser στέλνει ένα HTTP request κάθε λίγα δευτερόλεπτα, ζητώντας την τρέχουσα κατάσταση.

setInterval(async () => {

    const response = await fetch('/api/crawler/status');

    const status = await response.json();

 

    console.log(status);

}, 5000);

Κάθε πέντε δευτερόλεπτα πραγματοποιείται ένα νέο request.

Η τεχνική είναι απλή και εύκολη στην υλοποίηση. Ωστόσο, όταν υπάρχουν πολλοί χρήστες, μπορεί να δημιουργήσει περιττή κίνηση στον server.

Ακόμη και αν δεν έχει αλλάξει τίποτα, ο browser συνεχίζει να ρωτά.

Μια παραλλαγή είναι το Long Polling. Σε αυτή την περίπτωση, ο server καθυστερεί την απάντηση μέχρι να εμφανιστεί κάποιο νέο γεγονός ή να λήξει ένα χρονικό όριο.

3. Server-Sent Events: Όταν ο server ενημερώνει τον browser

Τα Server-Sent Events, γνωστά ως SSE, επιτρέπουν στον server να στέλνει διαδοχικές ενημερώσεις μέσα από μια ανοιχτή HTTP response.

Ο browser πραγματοποιεί ένα request και ο server διατηρεί τη ροή ανοιχτή.

Όταν εμφανίζονται νέα δεδομένα, τα αποστέλλει χωρίς να χρειάζεται νέο HTTP request για κάθε ενημέρωση.

Στη JavaScript χρησιμοποιούμε το EventSource API:

const events = new EventSource('/api/crawler/events');

 

events.onmessage = (event) => {

    console.log(event.data);

};

Για παράδειγμα, ένας crawler μπορεί να στέλνει:

10 προϊόντα ολοκληρώθηκαν

25 προϊόντα ολοκληρώθηκαν

50 προϊόντα ολοκληρώθηκαν

Η εργασία ολοκληρώθηκε

Ο browser εμφανίζει τις ενημερώσεις καθώς φτάνουν.

Η συγκεκριμένη τεχνολογία είναι χρήσιμη για dashboards, παρακολούθηση εργασιών, ενημερώσεις κατάστασης και streaming απαντήσεων από συστήματα τεχνητής νοημοσύνης.

Υπάρχει όμως ένας περιορισμός: Η ροή SSE μεταφέρει events από τον server προς τον client. Για να στείλει νέα δεδομένα ο browser, χρησιμοποιεί ξεχωριστά HTTP requests ή άλλον μηχανισμό.

4. WebSockets: Αμφίδρομη επικοινωνία σε πραγματικό χρόνο

Τα WebSockets αντιμετωπίζουν ένα διαφορετικό πρόβλημα.

Τι συμβαίνει όταν τόσο ο browser όσο και ο server πρέπει να στέλνουν δεδομένα οποιαδήποτε στιγμή;

Για παράδειγμα, σε μια εφαρμογή συνομιλίας δύο χρήστες ανταλλάσσουν μηνύματα συνεχώς.

Δεν θέλουμε ο browser να ρωτά κάθε δευτερόλεπτο αν εμφανίστηκε νέο μήνυμα.

Με ένα WebSocket δημιουργείται μια διαρκής, αμφίδρομη σύνδεση.

const socket = new WebSocket('wss://example.com/chat');

 

socket.onopen = () => {

    socket.send('Hello!');

};

 

socket.onmessage = (event) => {

    console.log(event.data);

};

Από τη στιγμή που εγκαθίσταται η σύνδεση, οι δύο πλευρές μπορούν να ανταλλάσσουν μηνύματα χωρίς να δημιουργείται νέο HTTP request για κάθε μήνυμα.

Τα WebSockets χρησιμοποιούνται σε live chat, συνεργατικές εφαρμογές, διαδικτυακά παιχνίδια και συστήματα που απαιτούν άμεση αμφίδρομη ενημέρωση.

Εδώ πρέπει να ξεχωρίσουμε κάτι: Το WebSocket δεν είναι το ίδιο με το HTTP, παρότι η εγκατάστασή του μπορεί να ξεκινά μέσω HTTP handshake.

5. TCP και UDP: Πώς μεταφέρονται τα δεδομένα;

Μέχρι τώρα εξετάσαμε τρόπους επικοινωνίας μεταξύ εφαρμογών.

Σε χαμηλότερο επίπεδο, όμως, υπάρχουν πρωτόκολλα μεταφοράς όπως το TCP και το UDP.

TCP: Αξιόπιστη μεταφορά δεδομένων

Το TCP (Transmission Control Protocol) δημιουργεί μια λογική σύνδεση μεταξύ δύο συσκευών.

Πριν αρχίσει η μεταφορά, πραγματοποιείται μια διαδικασία που ονομάζεται Three-Way Handshake.

Η διαδικασία περιλαμβάνει τρία βήματα:

Ο client στέλνει SYN.

Ο server απαντά με SYN-ACK.

Ο client επιβεβαιώνει με ACK.

Έπειτα ξεκινά η ανταλλαγή δεδομένων.

Το TCP χρησιμοποιεί επιβεβαιώσεις παραλαβής, αρίθμηση δεδομένων και επαναμεταδόσεις, ώστε η εφαρμογή να λαμβάνει μια αξιόπιστη και σωστά ταξινομημένη ροή bytes.

Αν χαθεί ένα τμήμα δεδομένων κατά τη μεταφορά, το TCP μπορεί να το στείλει ξανά.

UDP: Μεταφορά χωρίς εγγύηση παράδοσης

Το UDP (User Datagram Protocol) λειτουργεί διαφορετικά.

Δεν απαιτεί προηγούμενη δημιουργία σύνδεσης τύπου TCP.

Ο αποστολέας μπορεί να στείλει ένα datagram στη διεύθυνση IP και στη θύρα του παραλήπτη.

Το ίδιο το UDP δεν εξασφαλίζει ότι το datagram θα φτάσει, ούτε ότι διαφορετικά datagrams θα παραδοθούν με τη σωστή σειρά.

Αυτή η απλούστερη συμπεριφορά είναι χρήσιμη σε εφαρμογές που χρειάζονται μικρή καθυστέρηση και μπορούν να διαχειριστούν ενδεχόμενη απώλεια δεδομένων.

Γιατί το UDP χρησιμοποιείται σε εφαρμογές πραγματικού χρόνου;

Ας υποθέσουμε ότι συμμετέχουμε σε μια βιντεοκλήση.

Αν χαθεί ένα μικρό τμήμα της εικόνας, μπορεί να είναι προτιμότερο να συνεχιστεί η αναπαραγωγή, αντί να καθυστερήσει ολόκληρη η συνομιλία.

Το UDP επιτρέπει στην εφαρμογή να αποφασίσει πώς θα διαχειριστεί τις απώλειες.

Αυτό δεν σημαίνει ότι το TCP είναι πάντα αργό ή ότι το UDP είναι πάντα καλύτερο. Η καταλληλότητα εξαρτάται από τις απαιτήσεις της εφαρμογής και τον τρόπο που χρησιμοποιεί το κάθε πρωτόκολλο.

Επίσης, εφαρμογές μπορούν να υλοποιούν επιπλέον μηχανισμούς αξιοπιστίας πάνω από UDP, όπως συμβαίνει με το QUIC.

6. WebRTC: Όταν δύο browsers επικοινωνούν απευθείας

Το WebRTC (Web Real-Time Communication) επιτρέπει τη μεταφορά ήχου, βίντεο και δεδομένων σε πραγματικό χρόνο.

Μια συνηθισμένη εφαρμογή του είναι οι βιντεοκλήσεις μεταξύ δύο browsers.

Σε αντίθεση με μια κλασική εφαρμογή όπου κάθε μήνυμα περνά από τον application server, το WebRTC μπορεί να δημιουργήσει απευθείας επικοινωνία μεταξύ των συσκευών.

Αυτή η επικοινωνία ονομάζεται Peer-to-Peer ή P2P.

Όμως υπάρχει ένα πρόβλημα.

Οι περισσότεροι οικιακοί υπολογιστές δεν είναι απευθείας προσβάσιμοι από το Internet.

Τι είναι το NAT;

Ας υποθέσουμε ότι ένας υπολογιστής έχει την ιδιωτική IP:

192.168.1.10

Το router του σπιτιού διαθέτει μια δημόσια IPv4 διεύθυνση.

Το NAT (Network Address Translation) επιτρέπει σε συσκευές του τοπικού δικτύου να επικοινωνούν μέσω αυτής της δημόσιας διεύθυνσης, μεταφράζοντας τις σχετικές διευθύνσεις και, συχνά, τις θύρες.

Αυτό περιπλέκει τη δημιουργία απευθείας συνδέσεων από συσκευές που βρίσκονται πίσω από διαφορετικά routers.

Για να αντιμετωπίσει το πρόβλημα, το WebRTC χρησιμοποιεί διαδικασίες και βοηθητικές υπηρεσίες.

Signaling Server: Η αρχική γνωριμία

Πριν επικοινωνήσουν δύο browsers, πρέπει να ανταλλάξουν πληροφορίες για τις δυνατότητες και τις πιθανές διαδρομές σύνδεσής τους.

Η διαδικασία ονομάζεται signaling.

Ο signaling server μπορεί να είναι μια εφαρμογή PHP που εκτελείται μέσω Apache ή ένας ξεχωριστός server με WebSockets.

Ο Browser A στέλνει πληροφορίες στον signaling server και εκείνος τις μεταφέρει στον Browser B.

Η ανταλλαγή περιλαμβάνει συνήθως SDP και ICE candidates.

Ο signaling server δεν χρειάζεται να μεταφέρει τη φωνή ή το βίντεο της κλήσης.

STUN Server: Ανακάλυψη της εξωτερικής διεύθυνσης

Ο STUN server βοηθά έναν browser να ανακαλύψει τη δημόσια IP και τη θύρα από τις οποίες εμφανίζεται η επικοινωνία του.

Έτσι, οι browsers αποκτούν πληροφορίες που μπορούν να χρησιμοποιήσουν για να δοκιμάσουν απευθείας σύνδεση.

Ο STUN δεν λειτουργεί ως μεσάζοντας για τη μεταφορά της φωνής.

TURN Server: Όταν η απευθείας σύνδεση αποτυγχάνει

Υπάρχουν περιπτώσεις όπου οι περιορισμοί του NAT ή του firewall δεν επιτρέπουν την απευθείας επικοινωνία.

Τότε μπορεί να χρησιμοποιηθεί ένας TURN server.

Ο TURN λειτουργεί ως ενδιάμεσος μεταφοράς δεδομένων.

Η επικοινωνία ακολουθεί τη διαδρομή:

Browser A → TURN Server → Browser B

Αυτό επιτρέπει την πραγματοποίηση της κλήσης, αλλά δημιουργεί επιπλέον κίνηση στον TURN server.

Μπορούμε να δημιουργήσουμε δική μας υποδομή WebRTC;

Ναι.

Για παράδειγμα, σε έναν Linux server μπορούν να λειτουργούν ταυτόχρονα:

Apache και PHP για το signaling.

coturn για τις λειτουργίες STUN και TURN.

JavaScript στους browsers, χρησιμοποιώντας το RTCPeerConnection API.

Το coturn είναι λογισμικό ανοιχτού κώδικα που παρέχει STUN και TURN υπηρεσίες.

Δεν χρειάζεται υποχρεωτικά να αγοράσουμε κάποια εξωτερική υπηρεσία. Μπορούμε να φιλοξενήσουμε την υποδομή στον δικό μας server, λαμβάνοντας υπόψη το κόστος συντήρησης και bandwidth.

7. Push Notifications: Ενημερώσεις ακόμη και με κλειστή σελίδα

Οι ειδοποιήσεις push λειτουργούν με διαφορετική λογική.

Δεν απαιτούν να υπάρχει ανοιχτή μια ιστοσελίδα ή μια ενεργή WebSocket σύνδεση.

Σε μια εφαρμογή Web Push, ο browser ζητά άδεια από τον χρήστη και δημιουργεί μια push subscription.

Η εφαρμογή αποθηκεύει τις απαραίτητες πληροφορίες στον server.

Όταν υπάρχει νέα ειδοποίηση, ο server στέλνει ένα μήνυμα στο push service που αντιστοιχεί στη subscription.

Το push service αναλαμβάνει την παράδοση προς τον browser, σύμφωνα με τις δυνατότητες και τους περιορισμούς της πλατφόρμας.

Ένας service worker μπορεί να επεξεργαστεί το push event και να εμφανίσει ειδοποίηση.

Η ίδια γενική φιλοσοφία χρησιμοποιείται και στις εφαρμογές κινητών, αλλά με διαφορετικές υποδομές.

Στο Android χρησιμοποιείται ευρέως το Firebase Cloud Messaging (FCM), ενώ στο οικοσύστημα της Apple χρησιμοποιείται το Apple Push Notification service (APNs).

Ειδοποιήσεις μπορούν επίσης να λαμβάνουν desktop εφαρμογές, εφόσον υποστηρίζουν κάποιον κατάλληλο μηχανισμό.

Το κρίσιμο σημείο είναι ότι ο application server συνήθως δεν επικοινωνεί απευθείας με τη συσκευή μέσω Web Push. Χρησιμοποιεί την αντίστοιχη υπηρεσία παράδοσης.

8. HTTP/1.1, HTTP/2 και HTTP/3: Δεν είναι διαφορετικά HTTP Methods

Ένα ακόμη σημείο που συχνά δημιουργεί σύγχυση είναι η διαφορά ανάμεσα στις εκδόσεις HTTP.

Τα GET και POST περιγράφουν την επιθυμητή ενέργεια.

Οι εκδόσεις HTTP περιγράφουν διαφορετικούς τρόπους με τους οποίους οργανώνεται και μεταφέρεται η επικοινωνία.

Το HTTP/1.1 υποστηρίζει επαναχρησιμοποίηση TCP συνδέσεων.

Το HTTP/2 επιτρέπει την ταυτόχρονη μεταφορά πολλών HTTP streams μέσα από μία TCP σύνδεση.

Το HTTP/3 βασίζεται στο QUIC, ένα πρωτόκολλο που λειτουργεί πάνω από UDP και προσφέρει, μεταξύ άλλων, αξιόπιστα streams.

Επομένως, το HTTP δεν σημαίνει υποχρεωτικά TCP σε κάθε σύγχρονη υλοποίηση.

Αντίστοιχα, μια τεχνολογία όπως το SSE μπορεί να λειτουργεί πάνω από διαφορετικές εκδόσεις HTTP.

9. Ποια τεχνολογία πρέπει να χρησιμοποιήσουμε;

Δεν υπάρχει μία τεχνολογία που να είναι η καλύτερη για όλες τις εφαρμογές.

Η επιλογή εξαρτάται από το είδος της επικοινωνίας.

Σενάριο

Συνήθης επιλογή

Φόρτωση προϊόντων

HTTP GET

Αποθήκευση φόρμας

HTTP POST ή PATCH

Έλεγχος κατάστασης ανά 30 δευτερόλεπτα

Polling

Ζωντανή πρόοδος crawler

SSE

Live chat

WebSocket

Βιντεοκλήση

WebRTC

Ειδοποίηση με κλειστή ιστοσελίδα

Web Push

Αμφίδρομη ενημέρωση dashboard

WebSocket ή συνδυασμός HTTP/SSE

Για παράδειγμα, σε ένα σύστημα crawling προϊόντων θα μπορούσαμε να χρησιμοποιήσουμε τρεις διαφορετικές τεχνολογίες.

Ένα HTTP POST ξεκινά την εργασία.

Μια σύνδεση SSE ενημερώνει ζωντανά τον browser για την πρόοδό της.

Τέλος, ένα HTTP GET φορτώνει τα προϊόντα που αποθηκεύτηκαν στη βάση δεδομένων.

Δεν χρειάζεται να χρησιμοποιήσουμε WebSockets μόνο και μόνο επειδή η εφαρμογή προσφέρει live ενημερώσεις.

Συμπέρασμα

Οι σύγχρονες εφαρμογές δεν χρησιμοποιούν έναν μοναδικό τρόπο επικοινωνίας.

Το HTTP παραμένει βασικό εργαλείο για την ανταλλαγή αιτημάτων και απαντήσεων.

Το polling επιτρέπει περιοδικούς ελέγχους, ενώ τα Server-Sent Events προσφέρουν συνεχή ενημέρωση από τον server προς τον browser.

Τα WebSockets δημιουργούν μια αμφίδρομη σύνδεση, ενώ το WebRTC επιτρέπει επικοινωνία πραγματικού χρόνου μεταξύ συσκευών, συχνά χωρίς να μεταφέρονται τα δεδομένα μέσω του application server.

Τα Push Notifications επιτρέπουν την ενημέρωση του χρήστη ακόμη και όταν δεν έχει ανοιχτή την ιστοσελίδα.

Κάτω από αυτές τις τεχνολογίες λειτουργούν πρωτόκολλα όπως το TCP και το UDP, που καθορίζουν σημαντικές ιδιότητες της μεταφοράς των δεδομένων.

Η ουσία για έναν developer δεν είναι να χρησιμοποιεί πάντοτε την πιο σύνθετη τεχνολογία.

Είναι να καταλαβαίνει τι είδους επικοινωνία χρειάζεται η εφαρμογή του και να επιλέγει τον απλούστερο μηχανισμό που καλύπτει αξιόπιστα τις απαιτήσεις της.

Πηγές και περαιτέρω ανάγνωση

MDN — HTTP Overview

MDN — HTTP Request Methods

MDN — Server-Sent Events

MDN — WebSocket API

MDN — WebRTC API

MDN — Push API

RFC 9293 — TCP

RFC 768 — UDP

coturn — STUN/TURN Server

Πώς σου φάνηκε;

Efthimios Theotokatos

Η συντακτική ομάδα του CodeCraft καλύπτει τεχνολογία, AI, hardware και software.

Σχόλια

Φόρτωση σχολίων…