Сервис для отправки сообщений между пользователями, хранение сообщений
- Подключение к чату 1 to 1 через Websocket
- Сохранение сообщений в БД
- Получение истории чата
- Получение списка чатов
- Поддержка добавления различных типов сообщений (обычный текст, отправка предложения о встрече в виде сообщения)
- Поддержка редактирования и удаления сообщений
- Сервис должен быть распределенным для горизонтального масштабирования
Описание проблемы: т.к. Chat Service является stateful сервисом (Websocket соединение 2 юзеров и храненимые сообщения должны быть на 1 сервисе), то для роутинга к нужному контейнеру нужен Service Discovery, который будет распределять нагрузку между контейнерами, запоминать адрес и роутить запросы
Решение: Использовать message брокер и рассылать сообщения на все инстансы:
Реактивный масштабируемый чат на Kotlin + Spring + WebSockets / Habr
Описание проблемы: что лучше юзать ActiveMQ, ActiveMQ-artemis, RabbitMQ или Kafka для распределенного websocket чата?
Решение: Использовать ActiveMQ-artemis - так как нам low latency нужна, а не high throghput, а для этого подходят ActiveMQ-artemis, ActiveMQ и RabbitMQ, но т.к. ActiveMQ-artemis из коробки по умолчанию работает с вебсокетами, то выбор падает именно на ActiveMQ-artemis.
Подключится к вебсокету можно например вот так:
var socket = new SockJS('/ws');
var stompClient = Stomp.over(socket);Для отправки сообщения нужно вызвать ручку и добавить тело сообщения:
stompClient.send("/app/sendMessage", {}, JSON.stringify(messageRequest));Для подключения к топику чата по его UUID нужно подключиться к урлу который перебрасывается на брокер:
stompClient.connect({}, function (frame) {
stompClient.subscribe('/topic/chat/' + chatId, function (message) {
console.log('Received message: ' + message.body);
showMessage(JSON.parse(message.body).content);
});
});