Сообщения XMPP, потерянные на Android при переключении передачи данных (например, включение Wi-Fi, GSM <-> Wifi-переключатель)

Я разрабатываю приложение для чата в Android. Использование сервера XMPP. Сервер PHP перенесен в ejabber.

Мое уведомление работает правильно во всех сценариях. Но в одном случае я теряю сообщения XMPP. На самом деле я не получаю уведомления.

В деталях я отключу Wi-Fi или подключение к данным. И после отключения Wi-Fi или подключения к данным любое уведомление, отправленное мне, которое не получает. После того, как я включу Wi-Fi или соединение с данными, я не могу получить сообщения, которые были отправлены мне.

Я реализовал сервис в фоновом режиме. Что делает соединение xmpp всегда живым.

Я получаю эту ошибку, пока я отключу WiFi-соединение.

java.net.SocketException: sendto failed: EPIPE (Broken pipe) java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out) at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506) at libcore.io.IoBridge.sendto(IoBridge.java:475) at java.net.PlainSocketImpl.write(PlainSocketImpl.java:508) at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46) at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:270) at java.io.OutputStreamWriter.flushBytes(OutputStreamWriter.java:167) at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:158) at java.io.BufferedWriter.flush(BufferedWriter.java:124) at org.jivesoftware.smack.PacketWriter.writePackets(PacketWriter.java:286) at org.jivesoftware.smack.PacketWriter.access$12(PacketWriter.java:270) at org.jivesoftware.smack.PacketWriter$1.run(PacketWriter.java:137) Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe) at libcore.io.Posix.sendtoBytes(Native Method) at libcore.io.Posix.sendto(Posix.java:146) at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177) at libcore.io.IoBridge.sendto(IoBridge.java:473) ... 9 more at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:552) at libcore.io.IoBridge.recvfrom(IoBridge.java:516) at java.net.PlainSocketImpl.read(PlainSocketImpl.java:489) at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:241) at java.io.InputStreamReader.read(InputStreamReader.java:244) at java.io.BufferedReader.read(BufferedReader.java:310) at org.jivesoftware.smack.XMPPConnection$AliveReader.read(XMPPConnection.java:1122) at org.kxml2.io.KXmlParser.fillBuffer(KXmlParser.java:1496) at org.kxml2.io.KXmlParser.peekType(KXmlParser.java:979) at org.kxml2.io.KXmlParser.next(KXmlParser.java:346) at org.kxml2.io.KXmlParser.next(KXmlParser.java:310) at org.jivesoftware.smack.PacketReader.parsePackets(PacketReader.java:321) at org.jivesoftware.smack.PacketReader.access$1(PacketReader.java:216) at org.jivesoftware.smack.PacketReader$1.run(PacketReader.java:70) Caused by: libcore.io.ErrnoException: recvfrom failed: ETIMEDOUT (Connection timed out) at libcore.io.Posix.recvfromBytes(Native Method) at libcore.io.Posix.recvfrom(Posix.java:131) at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164) at libcore.io.IoBridge.recvfrom(IoBridge.java:513) ... 13 more 

Поэтому для установки mod_archive мне нужно сделать это, типичное: записать следующую строку в cmd. (Для ц. Ос)

Вход как root Создать новый каталог:

 mkdir ejabberd_archive_plugin cd ejabberd_archive_plugin 

Теперь получите последние модули ejabberd, используя следующую команду

 yum https://svn.process-one.net/ejabberd-modules cd ejabberd-modules/mod_archive/trunk ./build.sh 

Теперь перейдите в каталог ebin, используя следующий cmd и получите список всех * .beam-файлов для плагинов архива ejabberd.

 root@ns1 [/ejabberd_archive_plugin/ejabberd-modules/mod_archive/trunk/ebin]# ls –l 

Используя следующий cmd, вы получите список всех файлов ejabberd * .beam при настройке и настройке ejabberd.

 root@ns1 [/usr/lib64/ejabberd/ebin]# ls -l 

Теперь скопируйте все файлы * .beam (архивные плагины) в каталог ejabberd ebin, используя следующий cmd

 root@ns1 [/]# cp /ejabberd_archive_plugin/ejabberd-modules/mod_archive/trunk/ebin /usr/lib64/ejabberd/ebin 

Теперь перейдите по следующему URL-адресу и скопируйте все SQL-запросы и запустите в phpmyadmin (база данных ejabberd)

 https://svn.process-one.net/ejabberd-modules/mod_archive/trunk/src/mod_archive_odbc_mysql.sql 

Теперь настройте ejjaberd.cfg, используя следующий cmd

 root@ns1 [/etc/ejabberd]# vi ejabberd.cfg Add the following line into ejabberd.cfg file in modules configuration section {mod_archive_odbc, [{database_type, "mysql"}, {default_auto_save, true}, {enforce_default_auto_save, true}]}, 

Теперь перезапустите службу ejabberd.

 root@ns1 [/etc/ejabberd]# sudo service ejabberd restart 

Для этого вам нужны «связанные с потоком» соединения с поддержкой XEP-198 . Георг написал хорошую запись в блоге по этой теме: http://op-co.de/blog/posts/XEP-0198/ В основном это позволяет подтверждать строфу и возобновлять поток , что является чрезмерным, что вы хотите сделать в случае, например, Переключатель Wi-Fi <-> GSM.

Я заключил из stacktrace, что вы используете aSmack (который является Smack портирован на Android). Существует открытый запрос функции для реализации управления потоками в Smack: SMACK-333 . Фактически, я недавно начал работать над реализацией, но не могу назвать ETA.

Для этого вам нужно создать отдельный веб-сервис. Поэтому мы можем обрабатывать историю отправленного сообщения. Мы можем управлять автономным сообщением.

XEP-198 – единственное решение. Сделайте плагин для своего сервера и упростите управление потерянным сообщением. Может быть другое решение, но AFAIK, это было бы решением.

Вы можете изменить плагин архива, чтобы сохранить в нем идентификаторы сообщений.

Когда пользователь приходит в Интернет, вызывается веб-служба с полученным последним сообщением. Сервер может получить все более поздние сообщения, сохраненные на сервере. Я создал его так же и отлично работал.

Вы должны переучиваться после повторного подключения к Интернету каждый раз. Но имейте в виду, что если вы перейдете с одним и тем же ресурсом и тем же пользователем, даже если он находится в сети, тогда сервер будет вызывать ошибку потока (заменяется новым соединением), что сделает вас в автономном режиме, и вы не получите никакого сообщения. Для этого сначала отключите себя перед переходом. Попробуйте выполнить поиск по модулю Amp .