SSE Named Event Types — Sending Structured Events with event: Fields
In this tutorial, you will learn about SSE Named Event Types. We cover key concepts, practical examples, and best practices to help you master this topic.
SSE named event types use the event: field to specify the type of event being sent, allowing clients to listen for specific events and dispatch them to appropriate handlers rather than catching all messages in a single onmessage handler.
What You'll Learn
- How to define named events in SSE streams
- How to listen for specific event types on the client
- How to structure event data for different event types
Why It Matters
Without named events, clients receive all messages through a single onmessage handler. Named events enable clean Separation Of Concerns: a news feed can have article, alert, and sports-score events, each handled by different code paths.
Real-World Use
DodaTech's real-time dashboard uses named SSE events: price-update for stock prices, news-alert for breaking news, system-status for server health, and user-notification for personal alerts. Each event type is handled by a different UI component.
flowchart LR
S["SSE Server"] -->|"event: price-update\ndata: {...}"| C["Client"]
S -->|"event: news-alert\ndata: {...}"| C
S -->|"event: system-status\ndata: {...}"| C
C --> PU["PriceUpdate\nHandler"]
C --> NA["NewsAlert\nHandler"]
C --> SS["SystemStatus\nHandler"]
style S fill:#dbeafe,stroke:#2563eb
style PU fill:#bbf7d0,stroke:#16a34a
style NA fill:#fef3c7,stroke:#d97706
style SS fill:#fecaca,stroke:#dc2626
Server-Side Named Events
from flask import Flask, Response, stream_with_context
import json
import time
import random
app = Flask(__name__)
def generate_events():
while True:
# Price update event
yield f"event: price-update\n"
yield f"data: {json.dumps({'symbol': 'AAPL', 'price': random.uniform(150, 160), 'change': random.uniform(-2, 2)})}\n\n"
# News alert event
if random.random() < 0.3:
yield f"event: news-alert\n"
yield f"data: {json.dumps({'title': 'Breaking: Market Update', 'severity': 'high', 'timestamp': time.time()})}\n\n"
# System status event
yield f"event: system-status\n"
yield f"data: {json.dumps({'cpu': random.randint(20, 80), 'memory': random.randint(30, 70), 'connections': random.randint(100, 500)})}\n\n"
time.sleep(2)
@app.route('/events')
def stream():
return Response(
stream_with_context(generate_events()),
mimetype='text/event-stream',
headers={
'Cache-Control': 'no-cache',
'X-Accel-Buffering': 'no'
}
)
Client-Side Event Handling
const eventSource = new EventSource('/events');
// Named event handlers
eventSource.addEventListener('price-update', (event) => {
const data = JSON.parse(event.data);
updatePriceDisplay(data.symbol, data.price, data.change);
});
eventSource.addEventListener('news-alert', (event) => {
const data = JSON.parse(event.data);
showNotification(data.title, data.severity);
});
eventSource.addEventListener('system-status', (event) => {
const data = JSON.parse(event.data);
updateSystemMetrics(data);
});
// Fallback handler for unnamed events
eventSource.onmessage = (event) => {
console.log('Unnamed event received:', event.data);
};
Multiple Event Types with Shared Connection
def multi_event_stream():
"""Stream multiple event types on the same connection"""
events = [
("user-login", {"user": "jane@example.com", "ip": "192.168.1.1", "timestamp": time.time()}),
("file-upload", {"filename": "report.pdf", "size": 2048576, "status": "complete"}),
("error-log", {"service": "database", "code": "CONN_TIMEOUT", "severity": "warning"}),
("user-logout", {"user": "jane@example.com", "session_duration": 3600}),
]
for event_type, data in events:
yield f"event: {event_type}\n"
yield f"data: {json.dumps(data)}\n\n"
time.sleep(1)
@app.route('/api/events/activity')
def activity_stream():
return Response(
stream_with_context(multi_event_stream()),
mimetype='text/event-stream'
)
Common Mistakes
1. Not Including the event: Field
Without the event: field, the client receives the event through onmessage. Always include event: when you want named event handling.
2. Sending Invalid JSON in Data
The data: field must contain valid JSON. Use json.dumps() on the server and JSON.parse() on the client.
3. Forgetting the Double Newline
Each event must end with two newlines (\n\n). Without it, the client waits indefinitely for the event to complete.
4. Using Reserved Event Names
Avoid event names that conflict with EventSource API properties like message, error, open.
5. Not Handling Unknown Event Types
Clients should have a fallback for unrecognized event types. Log unknown events for debugging.
Practice Questions
- What field specifies the event type in SSE?
- How do you listen for a specific named event in JavaScript?
- What happens if you omit the event: field?
- How do you handle multiple event types on one connection?
- What delimiter ends each SSE event?
Answers
- The
event:field. 2.eventSource.addEventListener('event-name', handler). 3. The event is received throughonmessage. 4. Send different event types interleaved on the same stream. 5. Two newlines\n\n.
Challenge
Build a real-time notification system with named SSE events: info for general notifications, warning for important alerts, error for system errors, and success for completed operations. Each event type has different data fields and triggers different UI behaviors.
FAQ
Mini Project
Build a real-time monitoring dashboard with named SSE events: metric for server metrics (CPU, memory), alert for threshold violations, log for application logs, and status for service health. Each event type updates a different dashboard widget with appropriate formatting.
What's Next
- Learn about sending JSON data in SSE events
- Explore event IDs and last-event-id for reconnection
- Continue to retry and reconnection strategies
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro