Інтеграція Ably для real-time даних на сайті
Ably — managed real-time платформа з глобальною інфраструктурою, підтримкою pub/sub, presence та history. Відрізняється від Pusher вбудованою підтримкою WebSocket streams, збереженням історії сообщень та багатшим SDK.
Встановлення
npm install ably
Сервер — публікація даних
import Ably from 'ably';
const ably = new Ably.Rest({
key: process.env.ABLY_API_KEY
});
// Публікація оновлення ціни (наприклад, біржова котирування)
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 для кількох символів
async function publishBatch(updates: PriceUpdate[]) {
await Promise.all(
updates.map(u => publishPriceUpdate(u.symbol, u.price))
);
}
Токени авторизації (Ably Token Auth)
Ніколи не передавайте API ключ на клієнт — використовуйте token auth:
// Сервер генерує токен для клієнта
app.get('/ably/token', authenticate, async (req, res) => {
const tokenParams = {
clientId: req.user.id,
capability: {
// Що може робити цей клієнт
[`prices:*`]: ['subscribe'],
[`notifications:${req.user.id}`]: ['subscribe'],
[`user-actions:${req.user.id}`]: ['publish', 'subscribe']
},
ttl: 60 * 60 * 1000 // 1 година
};
const tokenRequest = await ably.auth.createTokenRequest(tokenParams);
res.json(tokenRequest);
});
Клієнт (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;
}
Історія сообщень
Ably зберігає історію — новий підписник може отримати пропущені сообщення:
// Отримати останні 100 сообщень з каналу
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);
}
Часові рамки
Базова інтеграція pub/sub з token auth: 1–2 дні.







