- Описание
- Отправленные решения
481. В потоке
Однажды один талантливый программист написал чат-бота. И всё было прекрасно, пока чат-ботом пользовался только он. Но когда он поделился ссылкой с друзьями — начался кошмар. Сообщения летели беспорядочно. Отправка сообщения не гарантировала, что оно отправится нужному человеку. Друзья стали получать чужие сообщения и начали догадываться: что-то тут не так. У вас ещё есть время! Помогите навести порядок, чтобы сообщения нашли своих получателей.
- Нужно написать клиент, который бы отображал полученные в чатах сообщения.
- Код будет выполняться в браузерной вкладке.
- Код должен уметь работать в нескольких вкладках, и все данные должны быть синхронизированы между вкладками.
- Новые сообщения приходят с сервера в виде апдейтов. Апдейт содержит информацию о новом, отредактированном или удалённом сообщении.
- Для неактивной вкладки
callback
не вызывается, но все сообщения должны быть отображены на всех вкладках. - Для отображения сообщений используйте функцию
renderMessages
, передавая ей все сообщения чата (вызывать можно в любой момент, так как функция перерендерит список). - Каждый апдейт имеет уникальный ID, начиная с 1 для первого апдейта и с последующим увеличением на 1 для каждого следующего апдейта.
- Сервер не гарантирует правильного порядка апдейтов, но клиент должен применять их в порядке возрастания номера ID.
Формат ввода
Апдейты идут потоком с сервера:
type Update = {
id: number; // ID апдейта. Нужно применять в порядке увеличения ID.
type: 'new' | 'updated' | 'deleted'; // Тип апдейта.
message: Message; // Сообщение.
}
type Message = {
id: number; // ID сообщения.
chatId: number; // ID чата, в который пришло сообщение.
body?: string; // Тело сообщения. Поле body отсутствует в update'ах, где type: 'deleted'.
};
У апдейтов разный статус:
- new — пришло новое сообщение;
- updated — обновить текущее сообщение;
- deleted — удалить сообщение.
Вам дан класс Chat
:
- напишите функцию, которая будет передана как
callback
в класс; - функция должна вызывать
renderMessages
.
class Chat {
#socket = new WebSocket("ws://localhost:8081");
constructor(callback) {
this.#socket.onmessage = (event) => {
const incomingMessage = JSON.parse(event.data);
// Update
callback(incomingMessage)
};
}
// {[chatId: number]: Message[]}
renderMessages(messages) {
console.log(JSON.stringify(messages))
}
}
Ваше решение должно быть выполнено на JavaScript и должно выглядеть следующим образом (копировать класс Chat
в решение не нужно, оставьте только инициализацию):
// Вспомогательный код (если нужен).
function callback() {
// Ваше решение.
}
// Инициализация класса чата с вашим колбэком.
const chat = new Chat(callback)
Запускаться ваше решение будет в браузере с Chromium.
Формат вывода
Функция renderMessage
ожидает:
{[chatId: number]: Message[]}
Сгруппированные по chatId сообщения:
{
...
chatId: [
{id, chatId, body},
{id, chatId, body}
]
}
Пример:
Сервер отправляет сообщения:
{"data":[
{"id":3,"type":"deleted","message":{"id":2,"chatId":1}},
{"id":1,"type":"new","message":{"id":1,"chatId":1,"body":"Text-1"}},
{"id":4,"type":"updated","message":{"id":1,"chatId":1,"body":"Text-1 updated"}},
{"id":2,"type":"new","message":{"id":2,"chatId":1,"body":"Text-10"}}
]}
Клиент получает их и рендерит (фиксируется последний отрендеренный результат):
{
"1": [
{
"id": 1,
"chatId": 1,
"body": "Text-1 updated"
}
]
}
Примечание
- Ваше решение будет запускаться в браузере под Chromium.
- По ссылке находится playground (чтоб упростить дебаг).
Ограничения
Ограничение времени
15 с
Ограничение памяти
640 МБ