To build a production-ready, scalable stock update system with real-time updates in Angular, you’ll want to combine a solid frontend WebSocket setup with a robust backend (like Node.js + Redis + Kafka or a managed service).
Real-Time Stock Updates in Angular
Features:
- Live stock prices pushed to frontend
- Scalable (1000s of clients)
- Low latency
- Production-ready (auth, error handling, reconnection, observables)
- Efficient resource use (pub/sub pattern)
Architecture
+---------------------+
| External Stock API | <---- Polls every few seconds or via Webhook
+---------------------+
|
v
+---------------------+
| Node.js Server | <---- Aggregator, pushes data
| with Redis Pub/Sub |
+---------------------+
|
WebSocket (Socket.IO)
|
+---------------+
| Angular Client|
+---------------+
Tech Stack
Component | Tool | Notes |
Frontend | Angular + Socket.IO-client | For real-time updates |
Backend | Node.js + Socket.IO | Real-time server |
Cache / Pub-Sub | Redis | Push latest stock data to all instances |
Optional | Kafka / RabbitMQ | For heavy loads / message queues |
External Stock API | Alpha Vantage, IEX Cloud, Finnhub | For stock data |
Backend (Node.js + Redis + Socket.IO)
1. Install dependencies
npm install express socket.io redis axios
2. Backend Code (server.js
)
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const axios = require('axios');
const redis = require('redis');
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: { origin: '*' }
});
const redisClient = redis.createClient();
redisClient.connect();
// Poll stock price every 5 seconds
async function fetchAndBroadcastStock() {
try {
const response = await axios.get('https://api.example.com/stock/GOOG');
const stockPrice = response.data.price;
// Store in Redis
await redisClient.set('stock:GOOG', stockPrice);
// Emit to all WebSocket clients
io.emit('stock:update', { symbol: 'GOOG', price: stockPrice });
} catch (error) {
console.error('Error fetching stock price:', error.message);
}
}
setInterval(fetchAndBroadcastStock, 5000);
// WebSocket connection
io.on('connection', (socket) => {
console.log('Client connected:', socket.id);
socket.on('disconnect', () => {
console.log('Client disconnected:', socket.id);
});
});
server.listen(3000, () => console.log('Server running on http://localhost:3000'));
Frontend (Angular + Socket.IO-client)
1. Install socket.io-client
npm install socket.io-client
2. Socket Service
// socket.service.ts
import { Injectable } from '@angular/core';
import { io, Socket } from 'socket.io-client';
import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class SocketService {
private socket: Socket;
constructor() {
this.socket = io('http://localhost:3000'); // or environment variable
}
getStockUpdates(): Observable<any> {
return new Observable(observer => {
this.socket.on('stock:update', (data) => {
observer.next(data);
});
return () => this.socket.disconnect();
});
}
}
3. Component
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { SocketService } from './socket.service';
@Component({
selector: 'app-root',
template: `<div *ngIf="price">GOOG: ${{ price }}</div>`
})
export class AppComponent implements OnInit {
price: number;
constructor(private socketService: SocketService) {}
ngOnInit() {
this.socketService.getStockUpdates().subscribe(data => {
this.price = data.price;
});
}
}
Production Best Practices
- Use environment variables (
.env
) for API keys and URLs
- Rate-limit external API calls
- Use Redis as pub/sub if horizontally scaling backend
- Enable HTTPS and use secure WebSocket (WSS)
- Add authentication for client connections (JWT on handshake)
- Auto-reconnect on frontend using Socket.IO’s built-in options
- Dockerize the backend for easy deployment
- Monitor with tools like Prometheus + Grafana
Optional Enhancements
- Use Kafka if you want true event streaming across services
- Add historical price chart using D3.js or Chart.js
- Support multiple stock symbols (not just GOOG)
- Use RxJS Subjects in Angular to create a real-time service layer
- Store recent updates in a database (PostgreSQL + TimescaleDB for time series)
Perfect start to add functional stock updates: Achieve a production-ready, scalable solution with functionality, scalability, and maintainability.