У меня есть БД с пользователями. Почти во всех операциях фигурирует уникальное id пользователя из БД. Мне нужно получить список всех онлайн пользователей с минимальной тратой ресурсов. Для этого я использую Socket io.
Задача звучит просто, но я ломаюсь уже второй день.Что попробовал я?
Первая мысль, которая пришла ко мне: почему бы не попытаться связать socket id с id из БД. Я просмотрел около 50 ответов из интернета, но так и не смог это сделать. Пожалуй, это было бы лучшим решением, но я так и не смог ничего поделать с встроенным алгоритмом Socket io.
Если вы знаете, как связать id Socket io и id из БД - это будет решением, опишите пожалуйста.
Дальше я придумал использовать структуру и сохранить туда объекты в формате {id пользователя из БД, id сокета}.
Но я встретил другую проблему: получение списка пользователями. Я не придумал ничего лучше, кроме как просто скинуть эту структуру пользователю, но это показалось мне плохой идеей, так как я буду вынужден скинуть и лишнюю информацию ( id сокета ). Я предполагаю, что эту мысль можно развить, но я встретил другое решение из официальной документации! Там предложили добавить сокету кастомное поле и закинуть туда id пользователя. Это похоже на костыли,но я выбрал этот вариант. Я добавил сокету поле realId и закинул туда id из бд:
socket.realId = +client.handshake.query.id;
Дальше я создал отсортированный список и начал добавлять туда онлайн id и удалять их по дисконекту ( сокет дисконнектится, и я выцепляю у него из полей realId и удалю из списка ). Этот способ казался мне идеальным. Я так и не понял, что я сделал не так, но тесты провалились: я зашёл с двух браузеров и создал 2 пользователей. Дальше я присоединяюсь и... У обоих браузеров один realId! Ошибка настолько неожиданная, что я даже сначала не поверил.
Вот мой код ( написан на ts и бесконечные @ts-ignore, так как первоначальная структура сокета не имела кастомного поля ):
this.server.once('connection', async (socket) => {
if (client.handshake.query.id == undefined || isNaN(+client.handshake.query.id)) return;
//@ts-ignore
socket.realId = +client.handshake.query.id;
//@ts-ignore
binaryInsert(this.onlineUsersId, socket.realId)
});
client.on("disconnect", async () => {
const index = binarySearch(this.onlineUsersId, client.realId)
this.onlineUsersId.splice(index, 1);
})
Я не знаю, как ещё решать эту проблему. Конечно, можно добавить поле isOnline пользователям в БД, но работа с этим съест больше ресурсов, чем все остальные функции! Может кто-нибудь помочь?