Ably Integration for Real-Time Data on Website
Ably is a managed real-time platform with global infrastructure, pub/sub support, presence and history. Differs from Pusher with built-in WebSocket streams support, message history retention and richer SDK.
Installation
npm install ably
Server — Data Publication
import Ably from 'ably';
const ably = new Ably.Rest({
key: process.env.ABLY_API_KEY
});
// Publish price update (e.g., stock quote)
async function publishPriceUpdate(symbol: string, price: number) {
const channel = ably.channels.get(`prices:${symbol}`);
await channel.publish('price-update', {
symbol,
price,
timestamp: Date.now(),
change: calculateChange(symbol, price)
});
}
// Bulk publish for multiple symbols
async function publishBatch(updates: PriceUpdate[]) {
await Promise.all(
updates.map(u => publishPriceUpdate(u.symbol, u.price))
);
}
Authorization Tokens (Ably Token Auth)
Never pass API key to client — use token auth:
// Server generates token for client
app.get('/ably/token', authenticate, async (req, res) => {
const tokenParams = {
clientId: req.user.id,
capability: {
// What this client can do
[`prices:*`]: ['subscribe'],
[`notifications:${req.user.id}`]: ['subscribe'],
[`user-actions:${req.user.id}`]: ['publish', 'subscribe']
},
ttl: 60 * 60 * 1000 // 1 hour
};
const tokenRequest = await ably.auth.createTokenRequest(tokenParams);
res.json(tokenRequest);
});
Client (React)
import Ably from 'ably';
import { useEffect, useState } from 'react';
function usePriceUpdates(symbols: string[]) {
const [prices, setPrices] = useState<Record<string, number>>({});
useEffect(() => {
const client = new Ably.Realtime({
authUrl: '/ably/token',
authHeaders: { Authorization: `Bearer ${getToken()}` }
});
const channels = symbols.map(symbol => {
const channel = client.channels.get(`prices:${symbol}`);
channel.subscribe('price-update', (message) => {
setPrices(prev => ({
...prev,
[message.data.symbol]: message.data.price
}));
});
return channel;
});
return () => {
channels.forEach(ch => ch.unsubscribe());
client.close();
};
}, [symbols.join(',')]);
return prices;
}
Message History
Ably retains history — new subscriber can get missed messages:
// Get last 100 messages from channel
const channel = client.channels.get('notifications');
const history = await channel.history({ limit: 100, direction: 'backwards' });
for (const item of history.items) {
console.log(item.data, item.timestamp);
}
Timeline
Basic pub/sub integration with token auth: 1–2 days.







