Smack Client - Пользователь по-прежнему "в сети", хотя соединение прервано

Я испытываю довольно странное поведение, используя smack для создания небольшого клиента/Бит XMPP. Я установил соединение, а также ConnectionListener и ChatManagerListener. Это работает отлично, и я могу общаться с моим приложением, которое работает на портативном устройстве.

Чтобы проверить поведение при потерянном подключении, я подключил кабель Ethernet портативного устройства. Я ожидал, что клиент XMPP потеряет соединение и что пользователь будет настроен "в автономном режиме" в списке друзей пользователей. Что происходит, так это то, что этот пользователь по-прежнему отображается как "онлайн", а ConnectionListener моего клиента ничего не срабатывает, будь то connectionClosed или reconnectionFailed или иначе.

Когда я снова подключаю кабель Ethernet, иногда это похоже на то, что соединение было все время живым. Выполняются автономные сообщения, и я могу снова поболтать, как раньше. В других случаях мой клиент полностью недоступен и не по порядку, кажется, что все слушатели ушли... Но никаких экскрементов не бросают.

Это довольно странное и неконтролируемое поведение, которое сделает весь клиент непригодным для меня, поскольку я не могу быть уверен, что клиент снова появится после того, как соединение будет объявлено.

Кто-нибудь еще сталкивался с такими проблемами или имел какие-то намеки на то, что (не) происходит?

При необходимости я могу предоставить свой код, но на самом деле он просто копирует и вставляет из документации Smack.

Ответ 1

На самом деле вы описываете два разных эффекта. Начните с названия, указанного в названии вашего вопроса: пользователь считается онлайн сервером, даже если соединение происходит внезапно и, следовательно, нечисто, отменено. Причина в том, что сервер еще не заметил отключение клиента, так как не было четкого завершения потока стропов XMPP. Большинство серверов XMPP проверяют клиентов с помощью ping каждые X минут. Если клиент не отвечает, он считается отключенным и отображается в автономном режиме (если это последний подключенный ресурс для этого JID). Этого не произошло и не редкость. Потому что иногда вы хотите иметь длинные таймауты (полчаса или дольше).

То же самое относится к другой стороне. Smack также отправляет XMPP за каждые X минут, если используется PingManager или PingManagerWithAlarmManager (для Android). Если есть проблема с используемым сокетом, генерируется исключение.

Надеюсь, что я могу указать вам в правильном направлении. Вы должны отлаживать для себя, почему соединение не прекращено с исключением в вашем случае.

Последнее: TCP-соединение может легко пережить некоторый тайм-аут, даже если кабель Ethernet подключен, а затем снова подключен. Существует много тайм-аутов на разных уровнях используемой модели OSI: NAT, TCP, XMPP и т.д.

Ответ 2

Вы слишком явно используете метод disconnect() для прекращения соединения, иначе серверу придется периодически пинговать вас и понимать, что вы ушли в автономный режим