Я разрабатываю pet-project мобильное приложение в котором есть возможность обмениваться real-time сообщениями. Сложность мессенеджера, с точки зрения функционала, минимальная, а именно:
1. Есть возможность общаться в личных сообщениях 1-1
2. Есть возможность общаться в групповом чате, которое создает приложение. Сам пользователь создать групповой чат не может
3. Пользователь может написать и прочитать сообщение.
4. Пользователь может видеть, что его сообщение прочитано / не прочитано
Никаких доп.возможностей в стиле прикреплений файлов, фоток, геопозиций нету.
Стек следующий: Go на бэкенде из-за коробочных горутин/каналов. Redis как кэш + pub/sub. PostgreSQL как хранилище.
Схема БД следующая
Задачи такие:
1 - Получать список всех чатов пользователя с последним сообщением в этом чате.
2 - В real-time обновлять сообщения в списке при поступлении новых сообщений
3 - При входе в конкретный чат обмениваться сообщениями в real-time
4 - При скроле чата подгружать данные из базы.
Как планирую сделать:
1. На бэкенде сделаю api для получения списка всех чатов. При входе в приложение буду посылать запрос на /api/chats и доставать из постгреса все чаты пользователя с последним сообщением. Результат сохранять в кэше.
2. При входе в приложение буду подключаться к сокету, который будет прослушивать канал в редисе на появление новых сообщений во всех чатах, чтобы обновлять список чатов при поступлении новых сообщений. Если прилетает новое сообщение, то обновлять кэш из п1.
3. При входе в конкретный чат будут подключаться к еще одному сокету и заходить на канал редиса. При отправке сообщения сохранять его в БД
4. При входе в конкретный чат подгружать из бд последние 20-30 сообщений. При скроле подгружать еще.
Вопросы, которые не могу понять:
1. Нормально ли держать несколько сокетных соединений для разных целей, таких как обновлять список чатов и сообщения в конкретном чате.
2. Верна ли та архитектура, которую я выбрал? Что можно улучшить?
3. При очень большом количестве сообщений подгрузка истории может стать узким местом для базы
4. По какому принципу лучше кешировать чаты? По ID пользователя или по ID чата или как-то еще?
5. Даже при небольшом количестве пользователей такая архитектура может сожрать всю память, т.к. придется хранить в кэше и все чаты юзера и историю и слушать несколько сокетов.
6. Может быть вместо кеша в редисе хранить данные в локальном кэше устройства?
Искал в гугле темы о создании чатов, но обычно там разбираются простейшие примеры с общением 1-1 или несколько человек в одном чате, что в моем случае не подходит.
P.S. в таблице messages так же есть поле is_read, которое я добавил уже позже, после рисования схемы, которое отвечает за "прочитано/не прочитано"