Фреймворк Fresh на JavaScript позволяет создавать высокопроизводительные веб-приложения с акцентом на серверный рендеринг и реактивное обновление интерфейса. Управление комнатами (Room Management) — ключевой компонент для приложений с функционалом чатов, совместной работы и игровых платформ, где требуется синхронизация состояния между множеством пользователей.
Комната в контексте Fresh представляет собой логическую единицу, в которой объединяются пользователи и контент. Основные задачи модуля управления комнатами включают:
Комнаты создаются на серверной стороне, используя объектную структуру для хранения состояния. Простейшая реализация может выглядеть следующим образом:
class Room {
constructor(id) {
this.id = id;
this.clients = new Set();
this.state = {};
}
addClient(client) {
this.clients.add(client);
client.send(JSON.stringify({ type: 'room_joined', roomId: this.id }));
}
removeClient(client) {
this.clients.delete(client);
client.send(JSON.stringify({ type: 'room_left', roomId: this.id }));
}
}
Ключевым моментом является использование Set для
хранения клиентов, что обеспечивает уникальность подключений и
эффективное управление памятью.
Создание новой комнаты выполняется через менеджер комнат:
class RoomManager {
constructor() {
this.rooms = new Map();
}
createRoom(id) {
if (!this.rooms.has(id)) {
const room = new Room(id);
this.rooms.set(id, room);
}
return this.rooms.get(id);
}
deleteRoom(id) {
this.rooms.delete(id);
}
getRoom(id) {
return this.rooms.get(id);
}
}
Участники подключаются к комнате через WebSocket или аналогичный двунаправленный канал. Добавление и удаление клиентов должно сопровождаться синхронизацией состояния:
function broadcastToRoom(room, message) {
room.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(message));
}
});
}
Использование функции broadcastToRoom позволяет
централизованно рассылать события, например обновления чата или
состояния игры.
Состояние комнаты может включать любую информацию: позиции игроков, список сообщений, настройки. Для минимизации нагрузки на сеть рекомендуется использовать диффы — только изменения состояния отправляются клиентам.
class Room {
constructor(id) {
this.id = id;
this.clients = new Set();
this.state = {};
}
updateState(newState) {
const diff = {};
for (const key in newState) {
if (this.state[key] !== newState[key]) {
diff[key] = newState[key];
}
}
Object.assign(this.state, diff);
this.broadcast(diff);
}
broadcast(diff) {
this.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify({ type: 'state_update', diff }));
}
});
}
}
Такой подход позволяет поддерживать согласованное состояние у всех участников комнаты без полной пересылки всех данных при каждом обновлении.
Fresh не содержит встроенной системы управления комнатами на уровне WebSocket, поэтому важно предусматривать обработку отключений и повторных подключений:
Пример таймаута:
class Room {
constructor(id) {
this.id = id;
this.clients = new Map(); // client -> lastPing
this.state = {};
}
addClient(client) {
this.clients.set(client, Date.now());
}
removeInactiveClients(timeout) {
const now = Date.now();
for (const [client, lastPing] of this.clients) {
if (now - lastPing > timeout) {
this.clients.delete(client);
}
}
}
}
Для приложений с большим количеством комнат необходимо учитывать:
Пример интеграции с Redis Pub/Sub:
import { createClient } from 'redis';
const redis = createClient();
async function publishState(roomId, diff) {
await redis.publish(`room:${roomId}`, JSON.stringify(diff));
}
async function subscribeRoom(roomId, callback) {
const subscriber = redis.duplicate();
await subscriber.connect();
await subscriber.subscribe(`room:${roomId}`, message => {
callback(JSON.parse(message));
});
}
Это позволяет синхронизировать состояние между несколькими инстансами Fresh и обеспечивать масштабируемость без потери данных.
Менеджер комнат, сами комнаты и клиенты образуют иерархическую структуру:
RoomManager
├─ Room 1
│ ├─ Client A
│ ├─ Client B
│ └─ state
├─ Room 2
│ ├─ Client C
│ └─ state
└─ Room N
Эта архитектура обеспечивает гибкость, масштабируемость и высокую производительность при реализации функционала чатов, совместных игр и других приложений с динамическим взаимодействием пользователей.