ejabberd Probleme bei der Nachrichtenzustellung

Mein ejabberd XMPP‑Server ist nun seit einiger Zeit in Betrieb. In der Zwischenzeit wiesen mich meine Chatpartner wiederholt darauf hin, dass sie des öfteren eine Fehlermeldung erhielten, weil ihre Nachrichten nicht an mich zugestellt werden konnten. Ich bin dem Fehler auf den Grund gegangen.

Ursachenforschung

Scheinbar trat der Fehler nur bei Nutzung des Mobile‑Clients auf. Häufig dann, wenn ich den Chat pausierte und das Smartphone kurz bei Seite legte. Ich vermutete darum gleich, dass die Ursache in der Kommunikation zwischen Server und Smartphone liegen muss. Mit einem Testnutzer konnte ich den Fehler schließlich reproduzieren.

Es ist bekannt, dass mobile Geräte allgemein nur eine unzuverlässige Datenverbindung besitzen. Anders als bei drahtgebundenen Netzwerken können drahtlose Verbindungen aus diversen Gründen plötzlich und unvorhersehbar unterbrochen werden. Zum Beispiel beim Übergang zwischen Funkzellen oder dem Wechsel zwischen WLAN und Funknetz. Einige Smartphones regeln im Standby‑Modus auch selbstständig die Funkverbindungen herunter, um Energie zu sparen.

Eingehende Nachrichten werden vom Server an den Empfänger gesendet, sofern dieser angemeldet ist. Der Nutzer bleibt online, auch wenn die Verbindung (kurzzeitig) unterbrochen wird. Tritt dabei eine Zeitüberschreitung der Zustellung und Bestätigung auf, sendet der Server eine Fehlernachricht (Bounce) an den Sender. Das Schaubild verdeutlicht die Situation.

Das XMPP‑Protokoll stammt aus einer Zeit, in der mobile Kommunikation noch kein Thema war. Daher ist es wenig auf die daraus resultierenden Anforderungen ausgelegt. Erst Erweiterungen geben dem Protokoll die nötige Robustheit. Ein FAQ‑Artikel auf der ejabberd Webseite widmet sich ausführlich diesem Thema.

Lösung

ejabberd enthält standarmäßig eine ganze Reihe von Modulen (Erweiterungen). Unter anderem das Modul mod_stream_management. Mit diesem wird aktiv der Nachrichtenfluss kontrolliert. Dazu gehören die Bestätigung von Nachrichten und Wiederaufnahme von Datenströmen.

Für das Modul exisitert eine Konfigurationseinstellung, die das Verhalten im Fall einer Zeitüberschreitung bestimmt.

modules:
  [...]
  mod_stream_mgmt:
  ##
  ## Deal with unreliable connection
  ## eg. clients in mobile networks
  ##
  resend_on_timeout: if_offline

Mit der Einstellung resend_on_timeout: if_offline wird ein erneuter Sendeversuch unternommen. Jedoch nur, wenn der Empfänger an keiner anderen Ressource angemeldet ist. Diese Konfiguration sollte den allermeisten Anforderungen genügen.