2016-02-02 3 views
1

Я создаю приложение для обмена мгновенными сообщениями на iOS, которое использует ejabberd. В настоящее время я тестирую функцию управления потоками и, в частности, возобновление, которое, как представляется, работает в большинстве случаев. Однако есть случай, я не понимаю, что я могу повторить через следующие шаги, принимая во внимание параметры: resume_timeout: 30, resend_on_timeout: if_offlineСтранные ошибки с управлением потоком в ejabberd

  • на начальном клиента A и клиента B связаны, никакие другие ресурсы не связаны
  • клиент B аварии или отсоединение в не чистом виде
  • клиент а начинает посылать кучу сообщений (10+) очень быстро
  • ejabberd посылает ACK-а для каждого сообщения, посланного подтвердите, что сообщения достигли сервера
  • a через 20 секунд после сбоя, B снова соединяется. В этот момент А получает ошибки для каждого сообщения, отправленного до того
<message xmlns="jabber:client" from="[email protected]" to="[email protected]/resourceID" type="error" id="CFBF4583-209A-4453-2567-CCCC7894827E"> 
    <body>test</body> 
    <active xmlns="http://jabber.org/protocol/chatstates" /> 
    <request xmlns="urn:xmpp:receipts" /> 
    <error code="503" type="cancel"> 
     <service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /> 
    </error> 
</message> 

Я попытался с ejabberd 16.01.

Это происходит в 80% случаев; иногда сообщения, отправленные A, правильно доставляются в B при повторном подключении в течение 30 секунд.

Мои вопросы:

  • это поведение правильно? Я ожидаю, что никакая ошибка не будет отклонена клиенту A, если ack уже получен для сообщения.
  • с resend_on_timeout установлен в if_offline, и никакой другой ресурс не подключен, я бы не ожидал ошибок. Я прав?

ответ

2
  • Управление потоком данных указывает, что сообщение получено вашим сервером. Это не означает, что сообщение обработано или доставлено на указанный адрес. Даже если он был доставлен по адресу, то это устройство все равно может вернуть ошибку для строфы.
  • Это действительно просто удар в темноте, но после того, как взгляд через код ejabberd, это может быть то, что происходит:

    1. [email protected]/ResourceB падает их связь, сейчас сеанс ожидает возобновления использования ResourceB ,
    2. Клиент B повторно подключается, не возобновляется (поскольку он разбился и потерял свое состояние).
    3. Клиент B связывает ресурс ResourceB еще раз.
    4. Теперь сервер должен завершить сеанс ожидания, ожидающий возобновления, потому что клиент B запросил тот же ресурс.
    5. Сервер проверяет наличие других сеансов, поскольку он установлен в if_offline.
    6. Сервер видит, что есть сеанс (новый сеанс), и поэтому выбирает отскок вместо повторной отправки.

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

+0

Это определенно имеет смысл. Нежелательно ли ejabberd проверять ресурс и повторно отправлять сообщения в этом конкретном случае вместо отправки ошибки отправителю? – theMoonlitKnight

+0

@theMoonlitKnight Есть много реберных случаев с XEP-0198, где сообщения могут потеряться. Если вы хотите убедиться, что вы их получите, вы должны использовать XEP-0313 для хранения сообщений на сервере, а затем их получения. – xnyhps

1

@xnyhps' является правильным, и я fixed этим конкретным углом случая для следующего выпуска ejabberd. Тем не менее, @xnyhps также правильна, что есть другие угловые случаи, поэтому, если вам нужна надежная доставка сообщений, вы должны использовать XEP-0313. Основной особенностью XEP-0198 является возобновление сеанса.

 Смежные вопросы

  • Нет связанных вопросов^_^