Ho passato l'ultima settimana a cercare di rintracciare i messaggi mancanti nella mia app di messaggistica XMPPFramework ed eJabberd. Ecco i passaggi completi che ho seguito per garantire la consegna dei messaggi e quali sono gli effetti di ogni passaggio.
Mod_offline
nel file di configurazione ejabberd.yml assicurarsi di avere questo nelle regole di accesso:
max_user_offline_messages:
admin: 5000
all: 100
e questo nella sezione moduli:
mod_offline:
access_max_user_messages: max_user_offline_messages
Quando il server sa che il destinatario di un messaggio è offline, lo memorizzerà e lo recapiterà quando si riconnetteranno.
Ping (XEP-199)
xmppPing = XMPPPing()
xmppPing.respondsToQueries = true
xmppPing.activate(xmppStream)
xmppAutoPing = XMPPAutoPing()
xmppAutoPing.pingInterval = 2 * 60
xmppAutoPing.pingTimeout = 10.0
xmppAutoPing.activate(xmppStream)
Ping si comporta come un battito cardiaco in modo che il server sa quando l'utente non è in linea, ma non scollegare normalmente. È una buona idea non fare affidamento su questo disconnettendo su applicationDidEnterBackground
ma quando il client perde connettività o lo streaming si disconnette per ragioni sconosciute c'è una finestra di tempo in cui un client è offline ma il server non lo sa ancora perché il ping wasn si aspetta fino a qualche tempo in futuro. In questo scenario il messaggio non viene consegnato e non viene memorizzato per il recapito offline.
flusso Management (XEP-198)
xmppStreamManagement = XMPPStreamManagement(storage: XMPPStreamManagementMemoryStorage(), dispatchQueue: dispatch_get_main_queue())
xmppStreamManagement.autoResume = true
xmppStreamManagement.addDelegate(self, delegateQueue: dispatch_get_main_queue())
xmppStreamManagement.activate(xmppStream)
e poi in xmppStreamDidAuthenticate
xmppStreamManagement.enableStreamManagementWithResumption(true, maxTimeout: 100)
Ci siamo quasi.Il passo finale è quello di tornare alla ejabberd.yml
e aggiungere questa riga alla sezione porte in ascolto sotto access: c2s
:
resend_on_timeout: true
flusso di gestione aggiunge req/strette di mano AKN dopo ogni consegna dei messaggi. A parte ciò, non avrà alcun effetto sul lato server a meno che non sia impostato resend_on_timeout
(che non è predefinito su eJabberd).
C'è un caso limite finale che deve essere considerato quando il riconoscimento di un messaggio ricevuto non arriva al server e decide di tenerlo per la consegna offline. La prossima volta che il client accede, è probabile che riceva un messaggio duplicato. Per gestirlo, impostiamo quel delegato per XMPPStreamManager. Implementare lo xmppStreamManagement getIsHandled:
e se il messaggio ha un corpo di chat, impostare isHandledPtr
su falso. Quando si costruisce un messaggio in uscita aggiungere un xmppElement con un ID univoco:
let xmppMessage = XMPPMessage(type: "chat", to: partnerJID)
let xmppElement = DDXMLElement(name: "message")
xmppElement.addAttributeWithName("id", stringValue: xmppStream.generateUUID())
xmppElement.addAttributeWithName("type", stringValue: "chat")
xmppElement.addAttributeWithName("to", stringValue: partnerJID.bare())
xmppMessage.addBody(message)
xmppMessage.addChild(xmppElement)
xmppMessage.addReceiptRequest()
xmppStream.sendElement(xmppMessage)
Poi, quando si riceve un messaggio, informare il gestore dei flussi che il messaggio è stato gestito con xmppStreamManager.markHandledStanzaId(message.from().resource)
Lo scopo di questa fase finale è quello di stabilire un identificatore univoco che è possibile aggiungere allo XMPPMessageArchivingCoreDataStorage
e verificare la presenza di duplicati prima della visualizzazione.
Questo è esattamente ciò che ho fatto. – xhsoldier
Grazie amico !! questo è davvero utile post .. – nikBhosale