Сообщения 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

Ответы

Ответ 1

Итак, чтобы установить 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.

[email protected] [/ejabberd_archive_plugin/ejabberd-modules/mod_archive/trunk/ebin]# ls –l

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

[email protected] [/usr/lib64/ejabberd/ebin]# ls -l

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

[email protected] [/]# 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

[email protected] [/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.

[email protected] [/etc/ejabberd]# sudo service ejabberd restart

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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