Интеграция 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 дня.







