Надежность транспорта через Websocket (потеря данных Socket.io при переподключении)
NodeJS, Socket.io
проблемаПредставьте, что есть 2 пользователяU1 & U2, подключенный к приложению через Socket.io. Алгоритм следующий:
U1 полностью теряет интернет-соединение (например, выключает интернет)U2 отправляет сообщениеU1.U1 пока не получает сообщение, потому что интернет не работаетсервер детектируетU1 отключение по тайм-ауту сердцебиенияU1 переподключается к socket.ioU1 никогда не получает сообщение отU2 - это потеряно на Шаге 4, я думаю.Возможное объяснениеЯ думаю, я понимаю, почему это происходит:
на шаге 4сервер убивает экземпляр сокета и очередь сообщенийU1 такжеБолее того на шаге 5U1 а такжесервер создать новое соединение (оно не используется повторно), поэтому, даже если сообщение все еще находится в очереди, предыдущее соединение в любом случае теряется.Нужна помощьКак я могу предотвратить такую потерю данных? Я должен использовать звуковые удары, потому что я не навсегда зависаю в приложении. Также я все еще должен дать возможность переподключиться, потому что, когда я развертываю новую версию приложения, я хочу нулевое время простоя.
Постскриптум То, что я называю «сообщение», - это не просто текстовое сообщение, которое я могу сохранить в базе данных, а ценное системное сообщение, доставка которого должна быть гарантирована, или пользовательский интерфейс испортит.
Спасибо!
Дополнение 1У меня уже есть система учетных записей пользователей. Более того, мое приложение уже сложное. Добавление статусов оффлайн / онлайн не поможет, потому что у меня уже есть такие вещи. Проблема в другом.
Проверьте шаг 2. На этом этапе мы техническине могу сказать, если U1 переходит в автономный режимОн просто теряет связь, скажем, на 2 секунды, вероятно, из-за плохого интернета. Таким образом, U2 отправляет ему сообщение, но U1 не получает его, потому что интернет все еще не работает (шаг 3). Шаг 4 необходим для обнаружения автономных пользователей, допустим, время ожидания составляет 60 секунд. В конце концов, через 10 секунд соединение с Интернетом для U1 будет установлено, и он снова подключится к socket.io. Но сообщение от U2 теряется в пространстве, потому что на сервере U1 было отключено по таймауту.
Это проблема, я не хочу 100% доставки.
РешениеСоберите emit (имя и данные emit) у пользователя {}, идентифицированного случайным emitID. Отправить выбросПодтвердите emit на стороне клиента (отправьте emit обратно на сервер с emitID)Если подтверждено - удалить объект из {}, идентифицированного по emitIDЕсли пользователь переподключен - проверьте {} для этого пользователя и выполните цикл, выполнив Шаг 1 для каждого объекта в {}При отключении и / или подключенном соединении {} для пользователя, если это необходимо
// Сервер const pendingEmits = {};
socket.on ('connection ', () => resendAllPendingLimits); socket.on ('подтвердите', (emitID) => {delete (pendingEmits [emitID]);});
// Клиент socket.on ('что-то', () => {socket.emit ('подтверждения', emitID);});