Not logged in. · Lost password · Register
Forum: MatriX RSS
Avatar
Stei #1
Member since Oct 2016 · 31 posts
Group memberships: Members
Show profile · Link to this post
Subject: Is an unavailable presence sent out when network disconnects?
I notice that when a device is disconnected from a network, eventually the OnClose() method fires. Does an unavailable presence automatically get sent out to all subscribers?

For example, if I have a cell phone with no Data service (only Wifi). If I walk out of range of the wifi, will an unavailable presence be automatically sent out by the server?

And another scenario; assume there are two clients, Client A and Client B. Also assume that Client B is abnormally disconnected from Wifi, but still appears as available. If client A sends a message to client B, when the server receives the message from A, will it attempt to send it to B? Although B is offline, but still appears as available, what will happen? Will the message get stored on the server and be sent to client B when he is actually back online, or will it send it to B instantly, and assume that B received it (meaning the message is lost)?

I think this blog post details my concerns:
http://op-co.de/blog/posts/XEP-0198/

(But does stream management determine whether client B actually received the msg?)

Would using SendAndAck() instead of just Send() solve this issue? For example, will the Callback function be triggered when the message has been confirmed to be delivered to the other user? Or will it let me know that, even though the other user appears to be available, the message was not actually delivered?

Digging deeper, I found the property XmppClient.StreamManagement. I realized I do not have this set to true (it is not being set in my code at all). By setting it to true, will that completely solve my issue above? Or is it already set to true by default?

Note: I am already using message delivery receipts, and its working fine, except for the above scenario (the server sends the msg to the offline client who still appears available, therefore the client can never sent a receipt back to the sender).
This post was edited 5 times, last on 2017-02-09, 12:02 by Stei.
Avatar
Alex #2
Member since Feb 2003 · 4327 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by Stei:
I notice that when a device is disconnected from a network, eventually the OnClose() method fires. Does an unavailable presence automatically get sent out to all subscribers?

For example, if I have a cell phone with no Data service (only Wifi). If I walk out of range of the wifi, will an unavailable presence be automatically sent out by the server?

When you are not using Stream Management, or BOSH with inactivity then your server should consider your connection as disconnected. The server should send the unavailable presence on your behalf.

Quote by Stei:
And another scenario; assume there are two clients, Client A and Client B. Also assume that Client B is abnormally disconnected from Wifi, but still appears as available. If client A sends a message to client B, when the server receives the message from A, will it attempt to send it to B? Although B is offline, but still appears as available, what will happen? Will the message get stored on the server and be sent to client B when he is actually back online, or will it send it to B instantly, and assume that B received it (meaning the message is lost)?

With sockets in many cases you can detect connection loss only when you try to send some data over the connection. So it could happen that the server still considers the client as online after a connection loss. When the server tries to send the data it should get a socket exception, and then as a result store the message offline for later delivery. Or return it with an error to the sending client. It should not get lost in this case.

Quote by Stei:
Would using SendAndAck() instead of just Send() solve this issue? For example, will the Callback function be triggered when the message has been confirmed to be delivered to the other user? Or will it let me know that, even though the other user appears to be available, the message was not actually delivered?

yes, see:

Quote by Definition  XEP-0198:
Acknowledging a previously-received ack element indicates that the stanza(s) sent since then have been "handled" by the server. By "handled" we mean that the server has accepted responsibility for a stanza or stanzas (e.g., to process the stanza(s) directly, deliver the stanza(s) to a local entity such as another connected client on the same server, or route the stanza(s) to a remote entity at a different server); until a stanza has been affirmed as handled by the server, that stanza is the responsibility of the sender (e.g., to resend it or generate an error if it is never affirmed as handled by the server).

Quote by Stei:
Digging deeper, I found the property XmppClient.StreamManagement. I realized I do not have this set to true (it is not being set in my code at all). By setting it to true, will that completely solve my issue above? Or is it already set to true by default?

Does your server support and advertise Stream Management in the stream features?

Quote by Stei:
Note: I am already using message delivery receipts, and its working fine, except for the above scenario (the server sends the msg to the offline client who still appears available, therefore the client can never sent a receipt back to the sender).
Stream management and message delivery receipts can solve this problem. But in both cases the resend logic must be implemented on the client side.

Stream Management can address also offline messages. Because the server can ack any stanza. So the server sends you an ack also for messages which end up in the offline message store.

Alex
Avatar
Stei #3
Member since Oct 2016 · 31 posts
Group memberships: Members
Show profile · Link to this post
Our server supports stream management. Now I'm trying to implement the client side logic for stream management but am having some issues. For example, I should keep count of the number of outbound messages sent. I put a counter in the xmppclient's OnStanzaSent method, and increment it by 1 every time its called. But after acking the server, the number it responds with is always less than the number of outbound stanzas sent. Also, I receive a message such as the one below (Got Answer:20 ,expected:19)

  1. [0:] SEND: <r xmlns="urn:xmpp:sm:3" />
  2. 02-10 10:58:21.959 I/MatriX  (19281): 10:58:21.96 countStanzasOut: 19
  3. [0:] RECEIVE: <a xmlns="urn:xmpp:sm:3" h="20" />
  4. 02-10 10:58:22.209 I/MatriX  (19281): 10:58:22.22 Got Answer:20 ,expected:19
  5. [0:] SEND: <Empty Keep-Alive message sent>
  6. 02-10 10:58:41.379 I/MatriX  (19281): 10:58:41.38 4d345da2-1851-4058-b03f-c48fe4e496c0 SOCKET SEND: 
  7. [0:] XMPPHelper - OnStanzaSent: 48 // this is the value that I increment in the OnStanzaSent method

What is the proper way to keep track of the count on the client-side? And why is the response from the server in the <a /> tag different than what is expected?

EDIT: I managed to keep track of the stanzas out with my own local variable, by incrementing it every time I send a message, presence, request iq, subscribe, enter room, etc. Though I notice Matrix seems to already keep track of this through the countStanzasOut variable; is it possible to access this?

Also as a side note: I just updated the Android version from 2.0.0.17 to 2.1.0, and when I set xmppClient.StreamResumption = true, I get this error in visual studio:

System.MissingMethodException: Method 'Matrix.Xmpp.Client.XmppClient.set_StreamResumption' not found.

And one more thing, when using SendAndAck(), the callback function is never triggered. Is this a bug, or am I understanding it incorrectly? Is the only way to manage <a /> elements on the client side by parsing the XML in OnReceiveXml()?
This post was edited 3 times, last on 2017-02-10, 05:06 by Stei.
Avatar
Alex #4
Member since Feb 2003 · 4327 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by Stei:
What is the proper way to keep track of the count on the client-side? And why is the response from the server in the <a /> tag different than what is expected?

every stanza which goes over the wire counts. A stanza is a packet of type iq, message or presence.
There are 2 counters, incoming and outgoing stanzas.

Quote by Stei:
EDIT: I managed to keep track of the stanzas out with my own local variable, by incrementing it every time I send a message, presence, request iq, subscribe, enter room, etc. Though I notice Matrix seems to already keep track of this through the countStanzasOut variable; is it possible to access this?

There is the event OnStreamManagementStanzaReceived which delivers the count to you.

Quote by Stei:
Also as a side note: I just updated the Android version from 2.0.0.17 to 2.1.0, and when I set xmppClient.StreamResumption = true, I get this error in visual studio:

System.MissingMethodException: Method 'Matrix.Xmpp.Client.XmppClient.set_StreamResumption' not found.

This is weird, its just a simple property backed by a member variable. We still have to support platforms and compilers which don't offer auto properties :(

  1. private bool m_StreamResumption     = true;
  2. /// <summary>
  3. /// When set to true MatriX automatically enables stream resumption as defined in XEP-0198: Stream Management.
  4. /// </summary>
  5. public bool StreamResumption
  6. {
  7.     get { return m_StreamResumption; }
  8.     set { m_StreamResumption = value; }
  9. }

Quote by Stei:
And one more thing, when using SendAndAck(), the callback function is never triggered. Is this a bug, or am I understanding it incorrectly? Is the only way to manage <a /> elements on the client side by parsing the XML in OnReceiveXml()?

This must be related to the count mismatch. Can you validate if your server is counting correct as defined in the protocol extension?

Alex
Avatar
Stei #5
Member since Oct 2016 · 31 posts
Group memberships: Members
Show profile · Link to this post
Ok, I think I understand how to properly implement message receipts and ack handling. But there is just one scenario that I need some advice on.

A sends a message to B. A requests an ack, and the server responds and says that the message has been received by the server. Now assume B was disconnected abnormally before receiving the message, and still appears online, so the server sends the message to B, and thinks B received the message. Of course, the only way to know B received the message is if B sends a receipt.

But when B logs back in, the message was never received, and it wasn't stored in offline storage on the server. So my question is, how and when to determine that A needs to resend the message? For example, if A receives an available presence from B, should A wait for 5 or 10 seconds for a message receipt, and if no receipt is received, then A should resend the message? Or is there a better way to handle this?

Or is the server smart enough to know that if a receipt is requested, and it sends the message to B, and then B goes to unavailable without sending a receipt, will the server know to resend the message? (In other words, if we send a message with a receipt request, and receive acknowledgement from the server that the server received it, does the server guarantee that it will eventually be sent to B?)
This post was edited on 2017-02-11, 14:12 by Stei.
Avatar
Alex #6
Member since Feb 2003 · 4327 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
See here again on how the responsibility for acks is defined in XEP-0198

Quote by XEP-1098:
Acknowledging a previously-received ack element indicates that the stanza(s) sent since then have been "handled" by the server. By "handled" we mean that the server has accepted responsibility for a stanza or stanzas (e.g., to process the stanza(s) directly, deliver the stanza(s) to a local entity such as another connected client on the same server, or route the stanza(s) to a remote entity at a different server); until a stanza has been affirmed as handled by the server, that stanza is the responsibility of the sender (e.g., to resend it or generate an error if it is never affirmed as handled by the server).

The responsibility for a server does not end when the stanza is received.
Avatar
Stei #7
Member since Oct 2016 · 31 posts
Group memberships: Members
Show profile · Link to this post
So once I receive an ack from the server for a particular stanza, the sender no longer needs to worry about it at all? An ack for a particular message stanza means that the server either stored it in offline storage, or has confirmed to deliver it to the receiver? If so, the server will still properly handle the edge-case where it thinks it sent a message to a user who was offline, but still appears as available? (Sender does not need to worry about this edge case, correct?)

Edit: OK, I think I understand now. XEP 0198 says:
Stanza Acknowledgements -- the ability to know if a stanza or series of stanzas has been received by one's peer.

So if an acknowledgement means that the message was received by the other user, what is the purpose of using message receipts if you are using stream management?
This post was edited on 2017-02-11, 15:27 by Stei.
Avatar
Alex #8
Member since Feb 2003 · 4327 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by Stei on 2017-02-11, 15:18:
So if an acknowledgement means that the message was received by the other user, what is the purpose of using message receipts if you are using stream management?

Message Receipts did exist before the Stream Management extensions were created. It depends on the use case and requirements. Its not that one is better than the other.

For example some cases which acks cannot solve:

  • Server delivered message fine over the socket, but your client crashed while or before processing it. The server only know that the message was delivered on TCP level.
  • There can be additional hops between the server and the client, eg. proxy servers. The server only know on TCP level that the message was received fine by the next destination.

Message receipts or fully end to end, doe snot matter for them on how many hops you have and what the networking layer is.

Alex
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Forum: MatriX RSS