smack подключиться к серверу xmpp с предыдущим идентификатором потока
Я создаю чат-приложение, используя xmpp поверх Ejabbered для сервера и smack для Android-клиента
Я установил соединение, вход в систему, отправляю и получаю сообщения, затем я столкнулся с проблемой отключения и повторного подключения пользовательской сети, которая была решена с помощью Reconnecting Manger в smack и xmpp-0198, однако есть случай, когда мне нужно создайте новое соединение в smack, но используйте предыдущий сеанс (поток), чтобы получить все сообщения, хранящиеся в этом сеансе (они не сохраняются в автономных сообщениях), и если я создаю новое соединение с новым идентификатором потока, пользовательские сообщения получают потерял.
поэтому есть конструктор соединений для реализации этого решения. или конфигурация на стороне сервера для хранения этих сообщений в автономных сообщениях
2 ответа
После долгих поисков я наконец обновил сервер Ejabberd до последней версии 17.03
где они добавили новый модуль mod_stream_mgmt и изменили поведение управления потоками, поэтому, когда я создаю новое соединение, оно получает привязку к старому и получает неотправленные и необработанные сообщения
для активации mod_stream_mgmt я использовал следующие конфигурации:
mod_stream_mgmt :
resume_timeout :60
resend_on_timeout: true
Примечание: я также активировал mod_ping на стороне сервера, я не знаю, имеет ли это прямое влияние на этот процесс и дело, но сейчас мои клиенты не пропускают никаких сообщений.
Я думаю, что одно из следующего решит вашу проблему:
- Первая проверка - включена ли mod_offline на стороне сервера.
- Если mod_offline включен, проверьте лимит автономных сообщений на стороне сервера. Это должно быть больше 0.
- Используйте PingManager, чтобы стабилизировать ваше соединение. Я здесь помещаю пример кода для использования PingManager в Android-
Во время инициации XMPPTcpConnection-
pingManager = PingManager.getInstanceFor(this.connection);
pingManager.registerPingFailedListener(new PingFailedListener() {
@Override
public void pingFailed() {
// session dropped, request for reconnection
}
});
Когда аутентификация XMPPTcpCOnnection-
@Override
public void authenticated(XMPPConnection connection, boolean resumed) {
configurePingManager();
}
private void configurePingManager() {
pingManager.setPingInterval(ACCORDING_SERVER_PING_INTERVAL);
pingManager.pingServerIfNecessary();
}
- Убедитесь, что stream_management включен как на стороне сервера, так и на стороне клиента. Я помещаю здесь пример кода, чтобы включить stream_management для клиентской части Android
xmppTcpConnection.setUseStreamManagement(истина); xmppTcpConnection.setUseStreamManagementResumption(истина);
Когда XMPPTcpCOnnection аутентифицируется, проверяя состояние сеанса, отправьте и запросите все ожидающие потоки, используя код ниже:
@Override
public void authenticated(XMPPConnection connection, boolean resumed) {
configurePingManager();
if (!resumed) {
try {
xmppTcpConnection.sendSmAcknowledgement();
xmppTcpConnection.requestSmAcknowledgement();
} catch (SmackException.NotConnectedException | StreamManagementException.StreamManagementNotEnabledException e) {
e.printStackTrace();
}
}
}
Надеюсь, что после всех этих шагов ваша проблема будет решена.