processone / ejabberd

Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP, MQTT, SIP Server)
https://www.process-one.net/en/ejabberd/
Other
6.1k stars 1.51k forks source link

PubSub: last published item should be sent after initial presence stanza #2132

Closed marcphilipp closed 6 years ago

marcphilipp commented 6 years ago

What version of ejabberd are you using?

17.09

What operating system (version) are you using?

CentOS

How did you install ejabberd (source, package, distribution)?

source

What did not work as expected? Are there error messages in the log? What was the unexpected behavior? What was the expected result?

We're using PubSub nodes of type flat where send_last_published_item is set to on_sub_and_presence. When a subscriber connects, ejabberd sends the last published item immediately after resource binding. At that point the client may not be ready, in our case it is still establishing a session. Instead, ejabberd should send the last published item after the initial presence stanza.

Here's our log:

SEND: <?xml version='1.0'?>

SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='example.com'>

RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" id="11651921228001032693" version="1.0" stream1:lang="en" from="example.com"/>

RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/></stream:features>

SEND: <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>

RECV: <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>

SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='example.com'>

RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" id="598287532970794816" version="1.0" stream1:lang="en" from="example.com"/>

RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></stream:features>

SEND: <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">**************</auth>

RECV: <success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>

SEND: <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' to='example.com'>

RECV: <stream:stream xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client" id="10368533127762481390" version="1.0" stream1:lang="en" from="example.com"/>

RECV: <stream:features xmlns:stream="http://etherx.jabber.org/streams"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/><session xmlns="urn:ietf:params:xml:ns:xmpp-session"><optional/></session><c xmlns="http://jabber.org/protocol/caps" ver="KlF0D0DjdfSR2opY8nSTR7J5Vas=" node="http://www.process-one.net/en/ejabberd/" hash="sha-1"/><sm xmlns="urn:xmpp:sm:2"/><sm xmlns="urn:xmpp:sm:3"/><csi xmlns="urn:xmpp:csi:0"/></stream:features>

SEND: <iq type="set" id="680A7EC5-45FD-4ECD-A595-BFE47ADA3984"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>

RECV: <iq xmlns="jabber:client" type="result" id="680A7EC5-45FD-4ECD-A595-BFE47ADA3984"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>59b1718f-6367-4509-b022-7889812a863a@example.com/71872476329944940932504002</jid></bind></iq>

SEND: <iq type="set" id="68261A2E-D608-4A65-8AC3-740973D0C22C"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>

RECV: <message xmlns="jabber:client" to="59b1718f-6367-4509-b022-7889812a863a@example.com/71872476329944940932504002" from="pubsub.example.com" type="headline"><event xmlns="http://jabber.org/protocol/pubsub#event"><items node="59b1718f-6367-4509-b022-7889812a863a"><item id="95E7F0C9-DFF5-4775-81E1-EB2809FCC4A9"><message xmlns="urn:xmpp:acme:ns:0">...</message></item></items></event><delay xmlns="urn:xmpp:delay" from="1635e9f0-2079-4f82-bade-e07b9e1495e3@example.com/67143792271467926922642242" stamp="2017-11-28T17:27:47.996114Z"/></message>

RECV: <iq xmlns="jabber:client" lang="en" to="59b1718f-6367-4509-b022-7889812a863a@example.com/71872476329944940932504002" from="59b1718f-6367-4509-b022-7889812a863a@example.com" type="result" id="68261A2E-D608-4A65-8AC3-740973D0C22C"/>

SEND: <presence type="available"/>

RECV: <presence xmlns="jabber:client" lang="en" to="59b1718f-6367-4509-b022-7889812a863a@example.com/71872476329944940932504002" from="59b1718f-6367-4509-b022-7889812a863a@example.com/71872476329944940932504002"/>

As you can see from the log the last published item message is received before the result IQ of the session creation and before the initial presence stanza.

cromain commented 6 years ago

From pubsub service point of view, it would cost waiting for initial user presence, requiring some dedicated state in c2s, as we don't want to trigger this on every presence packet. Waiting for 'initial presence' would also make mandatory for a bot listening to pubsub headlines to send presence, which makes no sense in this situation. For these reasons, as soon as session is alive, pubsub will send you the last items. This is an implementation choice. I don't see what you mean by "client may not be ready". if your application needs to have sent presence in order to handles messages, then you can still stack messages you receive until your app is ready to process them, no ?

marcphilipp commented 6 years ago

At least with XMPPFramework on iOS this completely breaks connecting. The workaround is to manually disable establishing a session (urn:ietf:params:xml:ns:xmpp-session) entirely: https://github.com/robbiehanson/XMPPFramework/blob/157bcd1d595b284b1765ea607eddc3d5d4127d84/Core/XMPPStream.h#L239-L253

cromain commented 6 years ago

@weiss indeed using c2s_self_presence hook is the key, your patch looks good.

marcphilipp commented 6 years ago

Thanks for the fix! 👍

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.