SSE (Server-Sent Events) — πρότυπο W3C που επιτρέπει στον διακομιστή να στέλνει δεδομένα ροής στον πελάτη μέσω μίας σύνδεσης HTTP σε μονόδρομη λειτουργία. Σε αντίθεση με το WebSocket, το SSE λειτουργεί πάνω από συνηθισμένο HTTP και δεν απαιτεί ειδικό πρωτόκολλο ή βιβλιοθήκη από την πλευρά του πελάτη. Σύμφωνα με την προδιαγραφή W3C HTML Living Standard (2025), το EventSource API υποστηρίζεται σε όλα τα σύγχρονα προγράμματα περιήγησης, συμπεριλαμβανομένων των Chrome, Firefox, Safari και Edge.
Κύρια σημεία
SSE (Server-Sent Events) — τεχνολογία που επιτρέπει στον διακομιστή ιστού να στέλνει δεδομένα στον πελάτη ανά πάσα στιγμή μετά τη δημιουργία της σύνδεσης. Έχει τυποποιηθεί από το WHATWG ως μέρος του HTML Living Standard και χρησιμοποιεί τον τύπο MIME text/event-stream. Το SSE υποστηρίζει μετάδοση δεδομένων κειμένου με δυνατότητα καθορισμού αναγνωριστικού μηνύματος, τύπου συμβάντος και καθυστέρησης επανασύνδεσης.
Σε αντίθεση με το WebSocket, το οποίο απαιτεί αμφίδρομο πρωτόκολλο και αίτημα αναβάθμισης, το SSE λειτουργεί πάνω από συνηθισμένο HTTP. Ο διακομιστής ορίζει την κεφαλίδα Content-Type: text/event-stream, στέλνει δεδομένα σε τμήματα και διατηρεί τη σύνδεση ανοιχτή. Ο πελάτης λαμβάνει δεδομένα μέσω του EventSource API του προγράμματος περιήγησης, το οποίο αναλύει αυτόματα τη ροή και δημιουργεί συμβάντα.
Σύμφωνα με δεδομένα CanIUse (2025), το EventSource API υποστηρίζεται στο 97,5% των προγραμμάτων περιήγησης παγκοσμίως. Δεν υποστηρίζεται στον Internet Explorer και σε ορισμένα προγράμματα περιήγησης κινητών (Samsung Internet έως έκδοση 7.0). Για αυτές τις περιπτώσεις υπάρχουν polyfill που εξομοιώνουν το EventSource μέσω XHR streaming. Το SSE δεν λειτουργεί με HTTP/1.1 pipelining, αλλά είναι πλήρως συμβατό με HTTP/2 server push.
SSE προτάθηκε ως μέρος της προδιαγραφής HTML5 το 2009 με το όνομα Server-Sent DOM Events. Η πρώτη υλοποίηση εμφανίστηκε στο Opera 9.0, στη συνέχεια στο Firefox 6.0 (2011), Chrome 9.0 (2011) και Safari 5.0 (2010). Το 2015 η προδιαγραφή διαχωρίστηκε σε ξεχωριστή ενότητα του HTML Living Standard. Παρά την ιστορία μιας δεκαετίας, το SSE παραμένει λιγότερο δημοφιλές από το WebSocket λόγω της μονόδρομης φύσης του.
Ο μηχανισμός λειτουργίας του SSE είναι ο εξής: ο πελάτης δημιουργεί ένα στιγμιότυπο EventSource με το URL του τελικού σημείου του διακομιστή. Το πρόγραμμα περιήγησης στέλνει ένα αίτημα GET με κεφαλίδα Accept: text/event-stream. Ο διακομιστής απαντά με κατάσταση 200 OK και κεφαλίδα Content-Type: text/event-stream, στη συνέχεια αρχίζει να στέλνει δεδομένα σε μορφή event-stream. Η σύνδεση παραμένει ανοιχτή έως ότου ο διακομιστής στείλει σήμα τερματισμού ή ο πελάτης καλέσει close().
Στην πλευρά του διακομιστή, τα δεδομένα αποστέλλονται σε τμήματα (chunked transfer encoding). Κάθε μπλοκ δεδομένων είναι ένα μήνυμα κειμένου που αποτελείται από γραμμές πεδίων (event, data, id, retry). Ο διακομιστής μπορεί να στέλνει μηνύματα ανά πάσα στιγμή, καθιστώντας το SSE ιδανικό για ειδοποιήσεις και ενημερώσεις κατάστασης. Η σύνδεση δεν απαιτεί συνεχή ανταλλαγή πακέτων heartbeat (όπως το WebSocket), αν και το πεδίο retry ελέγχει τη συχνότητα επανασύνδεσης.
Σύμφωνα με δεδομένα δοκιμών απόδοσης (2024), το SSE παρέχει απόδοση έως 10.000 μηνύματα ανά δευτερόλεπτο ανά σύνδεση με μέγεθος μηνύματος 256 byte. Στην πλευρά του διακομιστή, κάθε σύνδεση SSE καταναλώνει περίπου 5–10 KB μνήμης, επιτρέποντας σε έναν διακομιστή να υποστηρίζει 50.000+ ταυτόχρονες συνδέσεις με 1 GB RAM. Αυτό είναι σημαντικά λιγότερο από το WebSocket λόγω της απουσίας δυαδικού πρωτοκόλλου.
Μορφή text/event-stream — ένα απλό πρωτόκολλο κειμένου όπου κάθε μήνυμα αποτελείται από ονομασμένα πεδία που χωρίζονται με χαρακτήρες νέας γραμμής. Κάθε πεδίο έχει μορφή “ΌνομαΠεδίου: τιμή”. Τα μηνύματα χωρίζονται με δύο χαρακτήρες νέας γραμμής ( ).
Υποστηριζόμενα πεδία: event (τύπος συμβάντος, προεπιλογή message), data (συμβολοσειρά δεδομένων, μπορεί να είναι πολλαπλών γραμμών), id (τελευταίο αναγνωριστικό συμβάντος, αποθηκεύεται στο Last-Event-ID), retry (χρόνος επανασύνδεσης σε χιλιοστά του δευτερολέπτου). Τα σχόλια ξεκινούν με άνω και κάτω τελεία (:) και αγνοούνται από τον αναλυτή, αλλά μπορούν να χρησιμοποιηθούν για heartbeat.
| Πεδίο | Υποχρεωτικό | Σκοπός |
|---|---|---|
| event | Όχι | Τύπος συμβάντος (προεπιλογή message) |
| data | Ναι | Συμβολοσειρά δεδομένων μηνύματος |
| id | Όχι | Αναγνωριστικό συμβάντος για Last-Event-ID |
| retry | Όχι | Καθυστέρηση επανασύνδεσης σε ms |
: heartbeat comment
event: update
data: {"user": "Alice", "action": "typing"}
id: 1001
event: notification
data: {"type": "info", "text": "New version available"}
data: {"type": "action", "url": "/upgrade"}
retry: 3000
event: close
data: Session ended
EventSource API — η ενσωματωμένη διεπαφή του προγράμματος περιήγησης για λήψη SSE. Για να δημιουργηθεί μια σύνδεση, αρκεί να κληθεί ο κατασκευαστής με το URL του τελικού σημείου. Το EventSource δημιουργεί αυτόματα τη σύνδεση, διαχειρίζεται την επανασύνδεση και αναλύει τα εισερχόμενα μηνύματα σε συμβάντα JavaScript.
Συμβάντα EventSource: open (σύνδεση δημιουργήθηκε), message (ελήφθη μήνυμα χωρίς καθορισμό event), error (σφάλμα σύνδεσης). Για προσαρμοσμένα συμβάντα (event: custom) μπορεί να χρησιμοποιηθεί addEventListener με το όνομα του συμβάντος. Το EventSource στέλνει αυτόματα την κεφαλίδα Last-Event-ID κατά την επανασύνδεση, επιτρέποντας στον διακομιστή να συνεχίσει τη ροή από το σημείο διακοπής.
Σύμφωνα με την τεκμηρίωση MDN (2025), το EventSource υποστηρίζει CORS και μετάδοση διαπιστευτηρίων (withCredentials). Για μετάδοση προσαρμοσμένων κεφαλίδων ή σώματος αιτήματος, το EventSource δεν είναι κατάλληλο — απαιτείται χειροκίνητη υλοποίηση μέσω fetch + ReadableStream. Το EventSource δεν υποστηρίζει δυαδικά δεδομένα — μόνο κείμενο και JSON.
const eventSource = new EventSource('/api/events/stream');
eventSource.addEventListener('open', () => {
console.log('Σύνδεση SSE άνοιξε');
});
eventSource.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
console.log('Ελήφθη:', data);
renderUpdate(data);
});
eventSource.addEventListener('notification', (event) => {
const notification = JSON.parse(event.data);
showNotification(notification.text);
});
eventSource.addEventListener('error', (error) => {
console.error('Σφάλμα SSE:', error);
// Αυτόματη επανασύνδεση προγράμματος περιήγησης
});
// Κλείσιμο σύνδεσης
eventSource.close();
SSE και WebSocket — διαφορετικές τεχνολογίες για επικοινωνία σε πραγματικό χρόνο, η καθεμία με τα δικά της πλεονεκτήματα. Το WebSocket είναι κατάλληλο για αμφίδρομη ανταλλαγή δεδομένων (συνομιλίες, παιχνίδια, συνεργατική επεξεργασία), το SSE για μονόδρομες ροές από τον διακομιστή στον πελάτη (ειδοποιήσεις, ροές ειδήσεων, tickers).
Βασική διαφορά — το WebSocket απαιτεί αίτημα αναβάθμισης από HTTP/1.1 στο πρωτόκολλο WebSocket (ws://), το οποίο μπορεί να αποκλειστεί από εταιρικά proxy. Το SSE λειτουργεί πάνω από συνηθισμένο HTTP, περνά μέσα από όλα τα proxy και δεν απαιτεί ειδική διαμόρφωση διακομιστή. Το SSE είναι επίσης απλούστερο στην υλοποίηση — ο διακομιστής δεν χρειάζεται πρόσθετη βιβλιοθήκη, αρκεί να μορφοποιήσει σωστά την απάντηση HTTP.
Σύμφωνα με δεδομένα συγκριτικών δοκιμών (2024), σε μία διεργασία διακομιστή, το SSE υποστηρίζει 30–50% περισσότερες συνδέσεις από το WebSocket λόγω απλούστερου πρωτοκόλλου. Ωστόσο, η καθυστέρηση του SSE είναι μεγαλύτερη (50–200 ms έναντι 10–50 ms για WebSocket) επειδή το SSE χρησιμοποιεί chunked HTTP, όχι πλήρη αμφίδρομη ροή με δυαδικά πλαίσια.
| Χαρακτηριστικό | SSE | WebSocket |
|---|---|---|
| Κατεύθυνση | Διακομιστής → πελάτης | Αμφίδρομη |
| Πρωτόκολλο | HTTP (text/event-stream) | ws:// / wss:// (RFC 6455) |
| Προγράμματα περιήγησης | 97,5% (ενσωματωμένο EventSource) | 97% (ενσωματωμένο WebSocket) |
| Δεδομένα | Μόνο κείμενο / JSON | Κείμενο + δυαδικά (Blob, ArrayBuffer) |
| Χειρισμός proxy | Περνά από όλα τα proxy | Απαιτεί διαμόρφωση proxy |
| Επανασύνδεση | Αυτόματη (πρόγραμμα περιήγησης) | Χειροκίνητη υλοποίηση |
| Ιστορικό | Last-Event-ID | Χωρίς ενσωματωμένο ιστορικό |
Υλοποίηση SSE στον διακομιστή δεν απαιτεί βιβλιοθήκες — αρκεί να ορίσετε τις σωστές κεφαλίδες HTTP και να στείλετε δεδομένα σε μορφή text/event-stream. Ας δούμε ένα παράδειγμα σε Node.js χρησιμοποιώντας την ενσωματωμένη ενότητα http. Ο διακομιστής ορίζει τις κεφαλίδες Content-Type και Cache-Control, στη συνέχεια στέλνει μηνύματα κάθε N δευτερόλεπτα.
Σύμφωνα με MDN Web Docs (2025), οι υποχρεωτικές κεφαλίδες για SSE είναι: Content-Type: text/event-stream, Cache-Control: no-cache και Connection: keep-alive. Χωρίς Cache-Control, το πρόγραμμα περιήγησης μπορεί να αποθηκεύσει προσωρινά τη ροή SSE, με αποτέλεσμα τη διακοπή παράδοσης. Το Connection: keep-alive υποδεικνύει ρητά στο πρόγραμμα περιήγησης να διατηρεί τη σύνδεση ανοιχτή.
const http = require('http');
http.createServer((req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
let eventId = 0;
const interval = setInterval(() => {
eventId++;
res.write(`id: ${eventId}\n`);
res.write(`event: update\n`);
res.write(`data: {"χρόνος": "${new Date().toISOString()}", "id":${eventId}}\n\n`);
}, 2000);
req.on('close', () => {
clearInterval(interval);
});
}).listen(3000);
from flask import Response, Flask
import time
import json
app = Flask(__name__)
@app.route('/stream')
def stream():
def generate():
event_id = 0
while True:
event_id += 1
data = json.dumps(
{'ticker': 'AAPL', 'price': 150.25})
yield f'id: {event_id}\nevent: price\ndata: {data}\n\n'
time.sleep(1)
return Response(generate(),
mimetype='text/event-stream')
Χρήση SSE σε εφαρμογές κινητών περιορίζεται λόγω έλλειψης εγγενούς υλοποίησης EventSource για iOS και Android. Σε πλατφόρμες κινητών, το SSE υλοποιείται μέσω τρίτων βιβλιοθηκών: σε iOS — μέσω URLSession με NSURLProtocol, σε Android — μέσω OkHttp με υποστήριξη SSE (okhttp-sse). Για React Native και Flutter, διατίθενται πακέτα που εξομοιώνουν το EventSource.
Σε iOS η εγγενής υλοποίηση SSE είναι δυνατή μέσω URLSessionDataDelegate. Κατά τη λήψη δεδομένων στη μέθοδο urlSession(_:dataTask:didReceive:), η εφαρμογή συσσωρεύει buffer και αναλύει χειροκίνητα τη μορφή event-stream. Σύμφωνα με ιστολόγιο ανάπτυξης iOS (2024), η κατανάλωση μπαταρίας σε SSE σε iOS είναι 40% χαμηλότερη από ό,τι σε σταθερή σύνδεση WebSocket, λόγω απουσίας πακέτων heartbeat.
Σε Android το OkHttp παρέχει την κλάση EventSource.Factory για εγγραφή σε ροές SSE. Οι εφαρμογές Android μπορούν να χρησιμοποιούν SSE για ειδοποιήσεις όταν το FCM δεν είναι διαθέσιμο ή για συγχρονισμό δεδομένων στο παρασκήνιο. Το SSE σε Android λειτουργεί καλά με το WorkManager για μακροχρόνιες εργασίες παρασκηνίου. Σύμφωνα με την τεκμηρίωση OkHttp (2025), το okhttp-sse υποστηρίζει αυτόματη επανασύνδεση με προσαρμοσμένο listener.
Συχνές Ερωτήσεις
SSE — μονόδρομη μετάδοση (διακομιστής → πελάτης) μέσω HTTP, δεν απαιτεί βιβλιοθήκες στον πελάτη. WebSocket — αμφίδρομη μετάδοση με δυαδικό πρωτόκολλο. Το SSE είναι απλούστερο στην υλοποίηση, το WebSocket είναι κατάλληλο για εργασίες όπου ο πελάτης στέλνει επίσης δεδομένα.
Όχι, το SSE μεταδίδει μόνο δεδομένα κειμένου. Για δυαδικά δεδομένα (εικόνες, ήχος) απαιτείται κωδικοποίηση Base64, η οποία αυξάνει το μέγεθος κατά 33%. Για δυαδικές ροές, είναι καλύτερο να χρησιμοποιείτε WebSocket.
EventSource επανασυνδέεται αυτόματα σε περίπτωση διακοπής. Ο χρόνος καθυστέρησης ορίζεται από το πεδίο retry στη ροή (προεπιλογή 1000 ms). Κατά την επανασύνδεση, το πρόγραμμα περιήγησης στέλνει την κεφαλίδα Last-Event-ID, επιτρέποντας στον διακομιστή να συνεχίσει τη ροή από το σημείο διακοπής.
Κάθε πρόγραμμα περιήγησης έχει όριο στον αριθμό ταυτόχρονων συνδέσεων HTTP με έναν τομέα. Για HTTP/1.1 — 6–8 συνδέσεις ανά τομέα, για HTTP/2 — έως 100. Το SSE χρησιμοποιεί μία σύνδεση, επομένως δεν υπάρχει ανταγωνισμός με άλλα αιτήματα.
Το SSE είναι κατάλληλο μόνο για λήψη μηνυμάτων (εισερχόμενα). Για αποστολή μηνυμάτων (εξερχόμενα) απαιτείται ξεχωριστό αίτημα HTTP (POST). Για πλήρη συνομιλία, είναι πιο βολικό να χρησιμοποιείτε WebSocket ή Socket.IO με αμφίδρομη επικοινωνία σε μία σύνδεση.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης