In today's fast-paced web applications, users expect instant feedback. Traditional request-response cycles leave users waiting, especially for complex computations like astrology readings. What if you could stream insights in real-time as they're generated? That's where Server-Sent Events (SSE) shine.
The Challenge with Astrology APIs
Astrology calculations can be computationally intensive, especially when generating detailed birth charts or answering complex questions. The Vedika API provides AI-powered Vedic astrology insights, but waiting for the complete response can feel sluggish. SSE allows us to stream these insights as they're generated, creating a more responsive and engaging user experience.
Understanding Server-Sent Events
SSE is a server push technology enabling servers to send updates to clients over a single HTTP connection. Unlike WebSockets, SSE is simpler to implement and works over standard HTTP, making it perfect for real-time notifications, progress updates, or streaming data.
Implementing SSE with the Vedika API
Let's build a real-time astrology query interface using the Vedika API with SSE.
Step 1: Setting Up the SSE Endpoint
First, we'll create a server endpoint that establishes an SSE connection and streams the Vedika API response:
// server.js
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.use(express.json());
app.use(express.static('public'));
app.post('/api/astrology-stream', async (req, res) => {
const { question, birthDetails } = req.body;
// Set SSE headers
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
// Send initial connection event
res.write(`data: ${JSON.stringify({ type: 'connection', message: 'Connected to astrology stream' })}\n\n`);
try {
// Simulate streaming the Vedika API response
// In a real implementation, you'd need a version of the Vedika API that supports streaming
// For this example, we'll simulate the streaming
// Send initial processing message
res.write(`data: ${JSON.stringify({ type: 'processing', message: 'Calculating your birth chart...' })}\n\n`);
// Simulate delay
await new Promise(resolve => setTimeout(resolve, 1000));
// Send planetary positions
res.write(`data: ${JSON.stringify({
type: 'planetary-positions',
data: {
sun: { sign: 'Aries', degree: 15.2 },
moon: { sign: 'Taurus', degree: 8.7 },
// ... more planets
}
})}\n\n`);
// Send house positions
await new Promise(resolve => setTimeout(resolve, 800));
res.write(`data: ${JSON.stringify({
type: 'house-positions',
data: {
firstHouse: { sign: 'Gemini', cusp: 12.3 },
// ... more houses
}
})}\n\n`);
// Send analysis
await new Promise(resolve => setTimeout(resolve, 1200));
res.write(`data: ${JSON.stringify({
type: 'analysis',
message: 'Based on your birth chart, you have a strong influence of Mercury in your communication sector...'
})}\n\n`);
// Send final answer
await new Promise(resolve => setTimeout(resolve, 1500));
res.write(`data: ${JSON.stringify({
type: 'answer',
question,
answer: 'Your question about career opportunities points to a favorable period starting next month...'
})}\n\n`);
// Send completion event
res.write(`data: ${JSON.stringify({ type: 'complete', message: 'Reading complete' })}\n\n`);
} catch (error) {
res.write(`data: ${JSON.stringify({ type: 'error', message: error.message })}\n\n`);
} finally {
res.end();
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
Step 2: Client-Side SSE Implementation
Now, let's create the client-side code to connect to our SSE endpoint and display the streaming data:
html
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Real-time Astrology Insights</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
.container { background: #f9f9f9; padding: 20px; border-radius: 8px; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input, textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; }
button { background: #4CAF50; color: white; padding: 10px 15px; border: none; border-radius: 4px; cursor: pointer; }
button:disabled { background: #cccccc; }
#results { margin-top: 20px; }
.event { padding: 10px; margin: 5px 0; border-radius: 4px; }
.connection { background: #e3f2fd; }
.processing { background: #fff3e0; }
.planetary-positions { background: #e8f5e9; }
.house-positions { background: #f3e5f5; }
.analysis { background: #e0f7fa; }
.answer { background: #e8eaf6; }
.error { background: #ffebee; }
.complete { background: #e8f5e9; }
</style>
</head>
<body>
<div class="container">
<h1>Real-time Astrology Insights</h1>
<form id="astrologyForm">
<div class="form-group">
<label for="question">Your Question:</label>
<textarea id="question" rows="3" placeholder="Ask about your career, relationships, or any other life area..."></textarea>
</div>
<div class="form-group">
<label for="birthDate">Birth Date:</label>
<input type="datetime-local" id="birthDate" required>
</div>
<div class="form-group">
<label for="birthLat">Birth Latitude:</label>
<input type="number" id="birthLat" step="any" required>
</div>
<div class="form-group">
<label for="birthLng">Birth Longitude:</label>
<input type="number" id="birthLng" step="any" required>
</div>
<button type="submit" id="submitBtn">Get Insights</button>
</form>
<div id="results"></div>
</div>
<script>
document.getElementById('astrologyForm').addEventListener('submit', async (e) => {
e.preventDefault();
const submitBtn = document.getElementById('submitBtn');
const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = '';
// Get form values
const question = document.getElementById('question').value;
const birthDate = document.getElementById('birthDate').value;
const birthLat = parseFloat(document.getElementById('birthLat').value);
const birthLng = parseFloat(document.getElementById('birthLng').value);
// Disable submit button
submitBtn.disabled = true;
submitBtn.textContent = 'Processing...';
try {
// Create SSE connection
const eventSource = new EventSource('/api/astrology-stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
question,
birthDetails: {
datetime: birthDate,
lat: birthLat,
lng: birthLng
}
})
});
// Handle different event types
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
displayEvent(data);
};
eventSource.onerror = (error) => {
console.error('SSE Error:', error);
displayEvent({
type: 'error',
message: 'Connection error. Please try again.'
});
eventSource.close();
};
} catch (error) {
console.error('Error:', error);
displayEvent({
type: 'error',
message: 'Failed to connect to astrology service.'
});
} finally {
submitBtn.disabled = false;
submitBtn.textContent = 'Get Insights';
}
});
function displayEvent(data) {
const resultsDiv = document.getElementById('results');
const eventDiv = document.createElement('div');
eventDiv.className = `event ${data.type}`;
let content = '';
switch (data.type) {
case 'connection':
content
Top comments (0)